Spring @Transactional - 事务中的JPA上下文问题
我正在使用 Glassfish v3.1 上托管的 Spring + JSF + JPA 配置。 我遇到了 @Transactional 注释的一些奇怪的(至少对我来说)行为。这是我的简化示例:
@Transactional
public void associateGroupToRole(String role, String group) throws MyServiceException {
GroupEntity groupEntity = userDao.getGroupByName(group);
RoleEntity roleEntity = userDao.getRoleByName(role);
//some stuff
if(!roleEntity.getGroups().contains(groupEntity)) {
roleEntity.getGroups().add(groupEntity);
}
}
@Transactional
public void associateGroupToRole(RoleEntity roleEntity, GroupEntity groupEntity) throws MyServiceException {
//some stuff
if(!roleEntity.getGroups().contains(groupEntity)) {
roleEntity.getGroups().add(groupEntity);
}
}
事实证明,以实体作为参数的“associateGroupToRole”可以正常工作,而以字符串为参数的“associateGroupToRole”则不能。经过小修改并将代码从一种方法复制到另一种方法后:
@Transactional
public void associateGroupToRole(String role, String group) throws MyServiceException {
GroupEntity groupEntity = userDao.getGroupByName(group);
RoleEntity roleEntity = userDao.getRoleByName(role);
if(!roleEntity.getGroups().contains(groupEntity)) {
roleEntity.getGroups().add(groupEntity);
}
}
代码运行没有任何问题,并且所有内容都提交给数据库。我的问题是:上面的示例中可能有什么问题,事务上下文发生了什么(当从一个带注释的方法访问另一个方法时),以及为什么我的实体不再处于托管状态?
这是我的 Spring 配置:
<context:annotation-config />
<context:component-scan base-package="com.mypackage"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<tx:jta-transaction-manager/>
<tx:annotation-driven/>
如您所见,我正在使用 persistence.xml 文件,并且我的 EntityManager 使用 JNDI 连接到数据库。
I'm using Spring + JSF + JPA configuration hosted on Glassfish v3.1.
I'm experiencing some strange (at least for me) behavior of @Transactional annotation. Here is my simplified example:
@Transactional
public void associateGroupToRole(String role, String group) throws MyServiceException {
GroupEntity groupEntity = userDao.getGroupByName(group);
RoleEntity roleEntity = userDao.getRoleByName(role);
//some stuff
if(!roleEntity.getGroups().contains(groupEntity)) {
roleEntity.getGroups().add(groupEntity);
}
}
@Transactional
public void associateGroupToRole(RoleEntity roleEntity, GroupEntity groupEntity) throws MyServiceException {
//some stuff
if(!roleEntity.getGroups().contains(groupEntity)) {
roleEntity.getGroups().add(groupEntity);
}
}
It turns out that "associateGroupToRole" with Entities as arguments works correctly and the one with String - does not. After small modification and coping code from one method to another:
@Transactional
public void associateGroupToRole(String role, String group) throws MyServiceException {
GroupEntity groupEntity = userDao.getGroupByName(group);
RoleEntity roleEntity = userDao.getRoleByName(role);
if(!roleEntity.getGroups().contains(groupEntity)) {
roleEntity.getGroups().add(groupEntity);
}
}
The code runs without any problems and everything is committed to database. My question is: What might be wrong in above example, what is happening to transaction context (when accessing from one annotated method to another), and why my entities are no longer in managed state?
Here is my Spring configuration:
<context:annotation-config />
<context:component-scan base-package="com.mypackage"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<tx:jta-transaction-manager/>
<tx:annotation-driven/>
As you can see I'm using persistence.xml file and my EntityManager uses JNDI to connect to DB.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不幸的是,其他一些 DAO 代码中存在错误。请投票结束这个问题。
Unfortunately there was a bug in some other piece of DAO code. Please vote for close this question.