Я использую конфигурацию Spring + JSF + JPA, размещенную на Glassfish v3.1.
Я испытываю странное (по крайней мере для меня) поведение аннотации @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» с сущностями в качестве аргументов работает правильно, а с String - нет. После небольшой модификации и копирования кода из одного метода в другой:
@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 для подключения к БД.