Question

I'm facing a problem in my project: entityManager.flush() is not doing anything, and the flushing is only being done right before commit, when exiting the EJB.

My project runs on WebSphere 7. I'm using JPA2 through OpenJPA. I'm using Spring for Autowiring. I'm using Container Managed Transactions.

Relevant code snippets below

persistence.xml

<persistence-unit name="persistenceUnit" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <properties>
        <property name="openjpa.TransactionMode" value="managed" />
        <property name="openjpa.ConnectionFactoryMode" value="managed" />
        <property name="openjpa.DynamicEnhancementAgent" value="true" />
    <property name="openjpa.jdbc.DBDictionary" value="StoreCharsAsNumbers=false" />
        <property name="openjpa.Log" value="SQL=TRACE"/>
    </properties>
</persistence-unit>

applicationContext.xml

<!-- Configure a JPA vendor adapter -->
<bean id="openJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
    <property name="showSql" value="true" />
    <property name="generateDdl" value="false" />
</bean>

<!-- Entity Manager -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/myappDS"/>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="persistenceUnitName" value="persistenceUnit"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter" ref="openJpaVendorAdapter" />
</bean>

EJB3 Bean

@Stateless(name="JPABaseEntityServiceBean")
@Configurable
public class JPABaseEntityServiceBean implements JPABaseEntityService {

    Logger logger = LoggerFactory.getLogger(JPABaseEntityServiceBean.class);

    @Autowired
    JPABaseEntityDao jpaBaseEntityDao;

    public JPABaseEntity persist(JPABaseEntity jpaBaseEntity) {
        return jpaBaseEntityDao.persist(jpaBaseEntity);
    }

DAO:

@Repository
public class JPABaseEntityDao implements BaseEntityDao {

    @PersistenceContext
    transient EntityManager entityManager;

    public JPABaseEntity persist(JPABaseEntity jpaBaseEntity) {
        Date now = new Date();
        jpaBaseEntity.setCreatedBy(TO_DO_ME);
        jpaBaseEntity.setUpdatedBy(TO_DO_ME);
        jpaBaseEntity.setUpdatedOn(now);
        jpaBaseEntity.setCreatedOn(now);

        entityManager.persist(jpaBaseEntity);

        entityManager.flush();

        return jpaBaseEntity;
    }

The "INSERT" is being done only when leaving the EJB, meaning the entityManager.flush() inside the DAO is not working

Was it helpful?

Solution

Ok, resolved in a way

Seems like the problem was that the Entity Manager was not getting the Transaction from WebSphere (probably because the Entity Manager was being injected by Spring, I haven't investigated that deeply)

So what I did is make Spring control the transaction in the EntityManager:

1. added <tx:annotation-driven/> and <tx:jta-transaction-manager/> to applicationContext.xml
2. annotated the DAO methods with @Transactional

The overall transaction is still handled by the EJB, meaning it's still using CMT and JTA from WebSphere

I had a ton of problems in the way because of dependency hell (the one that got me the most was hibernate-core including JBoss's javax.transaction implementation, grr), but other than that everything seems to be working smoothly

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top