2

我已经实现了一个 EJB3 / JPA Web 服务,没有任何重大问题,现在我转向了一个 Spring-WS/JPA Web 服务。两者都被部署到 Glassfish。

我对 JPA 的理解有限,但默认情况下事务是容器管理的?你如何改变这个?有了 EJB3,事情就很简单了,因为我可以将其注入EntityManager到“DAO”中(下次再讨论!),@PersistentContext容器将负责事务划分。就基本配置而言,就是这样。由于容器使用 JTA,因此我在持久性单元上指定了事务类型“JTA”。在我的带有一个持久性单元的非常简单的示例应用程序中,我不必关心它的名称 - 如果您有多个持久性单元,事情会变得更复杂还是容器会处理这个问题?

现在我已经用 Spring-WS 构建了一个等效的 Web 服务,并重用了我的实体/dao,但我一直在努力让它工作。我在我的应用程序上下文中包含了EntityManagerFactory( LocalContainerEntityManagerFactoryBean) 以及JpaTransationManager(bean 对EntityManagerFactory) 的 bean 定义。我还包括了PersistenceAnnotationBeanPostProcessortx命名空间。我不会认为我需要做任何其他事情,但它不会部署没有可用于“null”错误的持久性提供程序。

我是否需要指定要为其创建管理器的实际持久性单元?

谢谢,

更新:

好的,我收到以下错误:javax.persistence.PersistenceException: No Persistence provider for EntityManager named null。

这可能是我对工厂/经理的弹簧配置:

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManager" />

<bean
    class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<tx:annotation-driven/>

我想我可能需要或注入其他东西......

另一个更新:

修复了该问题 - 使用的是LocalEntityManager而不是LocalContainerEntityManager.

现在我在持久化我的对象时遇到了问题。我有一个带有子对象作为属性的父对象。当我调用时,我可以看到子对象被持久化在日志中em.persist(parent),但父对象没有被持久化。

最后更新:

父对象被持久化了,但是在我尝试检索它之前事务还没有提交(我是在模拟而不是模拟)。想我现在已经掌握了它的要点。

4

1 回答 1

0

我对 JPA 的理解有限,但默认情况下事务是容器管理的?

在 Java EE 环境中,会话 bean 的默认实体管理器类型是容器管理事务范围

你如何改变这个?

具体改什么?在什么情况下?在 Java EE 环境中,您必须使用 Bean Managed Transaction (BMT) 会话 bean 并控制UserTransaction.

如果您有多个持久性单元,事情会变得更复杂还是容器会处理这个问题?

我不确定这个,它可能是特定于容器的。因此,如果您有多个持久性单元,我的建议是定义unitName.

现在我已经使用 Spring-WS 构建了一个等效的 Web 服务(...)我是否需要指定要为其创建管理器的实际持久性单元?

这不应该是必需的。本文对默认机制进行了很​​好的总结(也许文档也有解释,但我找不到简洁的东西):

Spring LocalContainerEntityManagerFactoryBean 从持久性单元描述符(例如 )加载持久性单元配置, META-INF/persistence.xml其名称等同于 persistenceUnitName在该工厂 bean 上指定的属性值(参见清单 1 和 2)。如果没有提供持久性单元名称,则选择持久性单元描述符中的第一个配置。将持久性管理器注入到带有注释的 Spring bean 的属性中@PersistenceContext是由一个特殊的 bean 后处理器处理的,该后处理器必须在 Spring 配置文件中注册,如清单 9 所示。

(...)

当 Spring 在 bean 属性上遇到 @PersistenceContext注释时,它使用注释unitName属性的值来定位 EntityManagerFactory具有匹配 persistenceUnitName属性值的生产工厂 bean,匹配 bean ID 作为后备。如果unitName注释中未指定属性,则 Spring 使用 EntityManagerFactorySpring 配置中定义的第一个生产工厂 bean。清单 10 中显示了一个使用 @PersistenceContext将事务范围EntityManager注入 Spring bean 的示例。(如果您的应用程序中只有一个持久性单元,您可以放心地不使用该unitName 属性。)(...)

回到你的问题,我的建议是:

  • persistence.xml使用您和 Spring 配置的相关位更新您的问题
  • 激活日志记录(特别是org.springframework.orm)以查看初始化时是否一切顺利
  • 看看你在指定时会得到什么unitName
于 2010-10-09T05:20:08.103 回答