Spring's EntityManager not persisting

Posted by Fernando Camargo on Stack Overflow See other posts from Stack Overflow or by Fernando Camargo
Published on 2012-04-04T14:46:54Z Indexed on 2012/04/05 11:29 UTC
Read the original article Hit count: 286

Well, my project was using EJB and JPA (with Hibernate), but I had to switch to Spring. Everything was working well before that. The EJB used to inject the EntityManager, controled the transaction, etc.

Ok, when I switched to Spring, I had a lot of problems because I'm new on Spring. But after everything is running, I have the problem: the data is never saved on database. I configured my Spring to control the transactions, I have spring beans used in JSF, that has spring services that do the hard work. This services have a EntityManager injected and use @Transactional REQUIRED. This services pass the EntityManager to a DAO that call entityManager.persist(bean).

The selects appears to work well, the JTA transaction appears to work well to (I saw in log), but the entity is not saved!

Here is the log:

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter: doFilterInternal() (linha 136): Opening JPA EntityManager in OpenEntityManagerInViewFilter

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.beans.factory.support.DefaultListableBeanFactory: doGetBean() (linha 245): Returning cached instance of singleton bean 'transactionManager'

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.hibernate3.HibernateTransactionManager: getTransaction() (linha 365): Creating new transaction with name [br.org.cni.pronatec.controller.service.MontanteServiceImpl.adicionarValor]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.hibernate3.HibernateTransactionManager: doBegin() (linha 493): Opened new Session [org.hibernate.impl.SessionImpl@2b2fe2f0] for Hibernate transaction

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.hibernate3.HibernateTransactionManager: doBegin() (linha 504): Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@2b2fe2f0]

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.hibernate3.HibernateTransactionManager: doBegin() (linha 569): Exposing Hibernate transaction as JDBC transaction [com.sun.gjc.spi.jdbc40.ConnectionHolder40@3bcd4840]

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler: doJoinTransaction() (linha 383): Joined JTA transaction


INFO: Hibernate: 
    select
        hibernate_sequence.nextval 
    from
        dual

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.hibernate3.HibernateTransactionManager: processCommit() (linha 752): Initiating transaction commit

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.hibernate3.HibernateTransactionManager: doCommit() (linha 652): Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@2b2fe2f0]

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.hibernate3.HibernateTransactionManager: doCleanupAfterCompletion() (linha 734): Closing Hibernate Session [org.hibernate.impl.SessionImpl@2b2fe2f0] after transaction

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.hibernate3.SessionFactoryUtils: closeSession() (linha 800): Closing Hibernate Session

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter: doFilterInternal() (linha 154): Closing JPA EntityManager in OpenEntityManagerInViewFilter

INFO: [Pronatec] - 04/04/2012 11:30:20 - [DEBUG] org.springframework.orm.jpa.EntityManagerFactoryUtils: closeEntityManager() (linha 343): Closing JPA EntityManager

In the log, I see it commiting the transaction, but I don't see the insert query (the Hibernate is printing any query). I also see that the Hibernate lookup to get the next value of the sequence ID. But after that, it never really inserts.

Here is the spring context configuration:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="PronatecPU" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
<property name="jpaProperties">
    <props>
    <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
    </props>
</property>
</bean>


<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
    <property name="transactionManagerName" value="java:/TransactionManager" />
<property name="userTransactionName" value="UserTransaction" />
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />


<tx:annotation-driven transaction-manager="transactionManager" />

Here is my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="PronatecPU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/pronatec</jta-data-source>
    <class>br.org.cni.pronatec.model.bean.AgendamentoBuscaSistec</class>
    <class>br.org.cni.pronatec.model.bean.AgendamentoExportacaoZeus</class>
    <class>br.org.cni.pronatec.model.bean.AgendamentoImportacaoZeus</class>
    <class>br.org.cni.pronatec.model.bean.Aluno</class>
    <class>br.org.cni.pronatec.model.bean.Curso</class>
    <class>br.org.cni.pronatec.model.bean.DepartamentoRegional</class>
    <class>br.org.cni.pronatec.model.bean.Dof</class>
    <class>br.org.cni.pronatec.model.bean.Escola</class>
    <class>br.org.cni.pronatec.model.bean.Inconsistencia</class>
    <class>br.org.cni.pronatec.model.bean.Matricula</class>
    <class>br.org.cni.pronatec.model.bean.Montante</class>
    <class>br.org.cni.pronatec.model.bean.ParametrosVingentes</class>
    <class>br.org.cni.pronatec.model.bean.TipoCurso</class>
    <class>br.org.cni.pronatec.model.bean.Turma</class>
    <class>br.org.cni.pronatec.model.bean.UnidadeFederativa</class>
    <class>br.org.cni.pronatec.model.bean.ValorAssistenciaEstudantil</class>
    <class>br.org.cni.pronatec.model.bean.ValorHora</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="current_session_context_class" value="thread"/>
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>
  </persistence-unit>
</persistence>

Here is my service that is injected in the managed bean:

@Service
@Scope("prototype")
@Transactional(propagation= Propagation.REQUIRED)
public class MontanteServiceImpl {
    // more code
    @PersistenceContext(unitName="PronatecPU", type= PersistenceContextType.EXTENDED)
    private EntityManager entityManager;
    // more code
    // The method that is called by another public method that do something before
    private void salvarMontante(Montante montante) {
        montante.setDataTransacao(new Date());

        MontanteDao montanteDao = new MontanteDao(entityManager);
        montanteDao.salvar(montante);
    }
    // more code
}

My MontanteDao inherits from a base DAO, like this:

public class MontanteDao extends BaseDao<Montante> {

    public MontanteDao(EntityManager entityManager) {
        super(entityManager);
    }

}

And the method that is called in BaseDao is this:

public void salvar(T bean) {
    entityManager.persist(bean);
}

Like you can see, it just pick the injected entityManager and call the persist() method. The transaction is being controlled by the Spring, like is printed in the log, but the insert query is never printed in log and it is never saved.

I'm sorry about my bad english. Thanks in advance for who helps.

© Stack Overflow or respective owner

Related posts about spring

Related posts about hibernate