Reputation: 24482
I have some issues after changing my backend from Hibernate to JPA (+Hibernate). I am using Websphere and container transaction management through org.springframework.transaction.jta.WebSphereUowTransactionManager. Some operations don't behave as expected:
DELETE OPERATION: If I don't flush the EntityManager manually it won't issue the delete, nothing happens actually.
@Transactional
@Override
public void deleteApplication(Integer appId) {
Application app = appDAO.findOne(appId);
//em.flush(); to force the flush(), otherwise it doesn't do anything
appDAO.delete(app);
}
INSERT WITH CASCADE OPERATION: The Application entity has a N:M relation with Attribute. I try to persist an Application with some Attribute added to its Application.attributes List. Right after the appDAO.save() I see a insert into Application sentence. However, there are never any inserts for the cascaded Attributes into the join table. Again, I need to manually flush() the em to issue de sql statements left.
@Transactional
@Override
public Application createApplication(Application application) {
appDAO.save(application);
//em.flush(); Needed to force the cascade into the join table
return application
}
I have tried changing the transactionManager for a non-container-managed one (org.springframework.orm.jpa.JpaTransactionManager) and it works perfectly without needing to use manual flush.
I am not using the persistence.xml file, following the approach introduced in Spring 3.1 (jtaDataSource + packagesToScan). However I have also tried with the traditional config with a persistence.xml file and I experienced the same wrong behaviour.
¿Any suggestions?
My setup:
<bean id="mainEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="mainPersistenceUnit"/>
<property name="jtaDataSource" ref="mainDataSource"/>
<property name="packagesToScan" ref="packages-mainEntityManagerFactory"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.flush_before_completion">true</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
</props>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
</bean>
<tx:annotation-driven order="0" />
<!-- Drives transactions using local JPA APIs -->
<bean name="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>
Upvotes: 1
Views: 1885
Reputation: 24482
In case someone has the same problem. The solution comes down to using
<prop key="hibernate.transaction.factory_class">org.hibernate.ejb.transaction.JoinableCMTTransactionFactory</prop>
instead of
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
Upvotes: 3