2

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

  • What do you mean by saying "leaving the EJB"? – Jean-Philippe Bond Jun 26 '13 at 18:46
  • After executing "return jpaBaseEntityDao.persist(jpaBaseEntity);" from JPABaseEntityServiceBean (right before returning to the Controller) – Felipe Weber Jun 26 '13 at 18:52
  • When you say "the INSERT is being done only when leaving the EJB", what do you mean exactly? The INSERT should be performed when you flush(), but the data won't be visible in the DB (or to other transactions) until the EJB's transaction is committed. – Brett Kail Jun 26 '13 at 21:18
  • Hi bkail; I'm saying that the INSERT is not being performed at all when I flush() – Felipe Weber Jun 26 '13 at 23:21

1 Answers1

1

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