codependent
codependent

Reputation: 24482

Spring 3.2 + JPA (with Hibernate 3.6) + Websphere 8 (JTA) not flushing/commiting some operations

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

Answers (1)

codependent
codependent

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

Related Questions