Spring3 JPA (Hibernate4) not persisted

I have an application using Spring 3.2.3 and Hibernate 4.2.1.Final. I made several configurations and the application works very well in a test environment using HSQLDB, etc.

But when the application is deployed, it almost works fine. An entity is created, but never preserved. I see JPA logs:

Hibernate: Select nextval ('TASK_SEQ')

But the insert never appears = (

Using configuration:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> <context:component-scan base-package="br.com.company" /> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> <property name="persistenceUnitName" value="spring_pu" /> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <context:annotation-config /> <tx:annotation-driven transaction-manager="transactionManager" /> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> </beans> 

persistence.xml

 <?xml version="1.0" encoding="UTF-8"?> <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_2_0.xsd" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name="spring_pu" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>br.com.company.core.entities.Task</class> <properties> <property name="hibernate.connection.autocommit" value="true" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" /> <property name="hibernate.connection.url" value="jdbc:postgresql://127.0.0.1:5432/companyDB" /> <property name="hibernate.connection.user" value="postgres" /> <property name="hibernate.connection.password" value="*****" /> </properties> </persistence-unit> </persistence> 

Essence:

 @Entity @Table(name = "TASK") public class Task implements Serializable { private static final long serialVersionUID = -6262731134419520342L; @Id @Column(name = "ID") @GeneratedValue(generator = "TASK_SEQ", strategy = GenerationType.SEQUENCE) @SequenceGenerator(sequenceName = "TASK_SEQ", name = "TASK_SEQ") private long id; @Column(name = "DESCRIPTION") private String description; @Column(name = "FINISHED") private boolean fininshed; @Temporal(TemporalType.TIMESTAMP) @Column(name = "FINISH_DATE") private Date finishDate; //getters and setter below } 

And finally, the service:

 @Service public class TaskService { @PersistenceContext private EntityManager entityManager; @Transactional(propagation = Propagation.REQUIRED) public void createTask(Task task) { <b>//invoked method</b> entityManager.persist(task); } 

As I said, there are no exceptions, but the entity is not preserved, as in tests. Thanks!

Edit: I also tried removing the contents of persistence.xml to the Spring data source, and the problem is still the same:

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"> <property name="driverClassName" value="org.postgresql.Driver" /> <property name="url" value="jdbc:postgresql://127.0.0.1:5432/KCILDS" /> <property name="username" value="postgres" /> <property name="password" value="*****" /> </bean> <context:component-scan base-package="br.com.company" /> <bean id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="br.com.company.core.entities" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> <property name="jpaProperties"> <props> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="myEntityManagerFactory" /> </bean> <context:annotation-config /> <tx:annotation-driven transaction-manager="transactionManager" /> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> </beans> 

DECISION:

I will abandon the xml configuration. Nothing seems to work with this anymore. By reading more about trends and big configuration, I ended up successfully setting up java configuration and with a few extra tweaks. See below:

  @Configuration @EnableTransactionManagement @ComponentScan("br.com.company") public class PersistenceJPAConfig { @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); factoryBean.setDataSource(this.directDataSource()); factoryBean.setPackagesToScan(new String[] { "br.com.company" }); HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setShowSql(true); factoryBean.setJpaVendorAdapter(vendorAdapter); factoryBean.setJpaProperties(this.additionlProperties()); return factoryBean; } private Properties additionlProperties() { Properties properties = new Properties(); properties.put("database", "POSTGRESQL"); properties.put("databasePlatform", "org.hibernate.dialect.PostgreSQLDialect"); properties.put(Environment.SHOW_SQL, true); properties.put(Environment.FORMAT_SQL, true); return properties; } // now reasearch how to make it an environment configuration // @Bean // public DataSource dataSource() { // JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup(); // jndiDataSourceLookup.setResourceRef(true); // return jndiDataSourceLookup.getDataSource("jdbc/mybank"); // } @Bean public DataSource directDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.postgresql.Driver"); dataSource.setUrl("jdbc:postgresql://127.0.0.1:5432/MyBank"); dataSource.setUsername("postgres"); dataSource.setPassword("*******"); return dataSource; } @Bean //still trying to make a JTA Transaction public PlatformTransactionManager transactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(this.entityManagerFactoryBean().getObject()); return transactionManager; } @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); } } 
+1
source share
4 answers

First you must enable the PersistenceAnnotationBeanPostProcessor bean, for example:

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

As described in the Spring 3.1.x doc, section 14.5.2 :

Spring can understand @PersistenceUnit and @PersistenceContext annotations both at the field level and at the method level if PersistenceAnnotationBeanPostProcessor is enabled.

Another thing is to make sure your TaskService scanned. According to the published Spring configuration file, only the br.com.company package is br.com.company , so the TaskService should be under this package.

EDIT

You should use @Transactional methods for public that implement the interface . By default, the recommendation annotation is implemented by Spring through a simple Java Proxy that requires an interface.

As described in section 8.1.3 AOP Proxies :

Spring AOP by default uses standard J2SE dynamic proxies for AOP proxies. This allows any interface (or set of interfaces) to be proxied.

Of course, this also means that the TaskService must reference other beans through this interface.

+2
source

I ran into a problem similar to that described. I found the problem in misusing @Transactional notation, in particular, I used javax.transaction.Transactional incorrectly instead of org.springframework.transaction.annotation.Transactional

Take a look at importing your "@Service".

A detailed description of the difference can be found here in javax.transaction.Transactional vs org.springframework.transaction.annotation.Transactional

+1
source

Because the TaskService defined as a service, therefore, the Spring container will not support transactions for CRUD operations. You must delegate the CRUD operations to another bean - the normal I suffix them with the help of Managers.

Thus, this will be the complete hierarchy of the transaction workflow:

  • Create a regular bean. Say TaskManager
  • Embedding a newly created class in a TaskService

@Resource (name = "taskManager")

TaskManager taskManager;

3. Inject EntityManager , etc. In a newly created class class

4. Put all the CRUD methods in the manager class

5. Call these methods from the service

Call hierarchy: Tools → Manager → DAO → Entity Manager

Now you can save your essence.

0
source

I would first notice some obvious things twice: was there a task type from br.com.company.Task and not another java api Task?

If you still have the same problem, there might be something wrong with your transaction management. Try to clear the entityManager after you persist. Typically, an entityManager should automatically hide at the end of transactions:

 @Transactional(propagation = Propagation.REQUIRED) public void createTask(Task task) { entityManager.persist(task); entityManager.flush(task); } 

If you have a problem with the transaction manager, try instead of specifying the data source inside persistence.xml, create it on spring xml and use the dataSource property for JpaTransactionManager

Also set the following log4j logger to see the start / end of the transaction and the SQL released by sleeping:

 log4j.logger.org.hibernate.SQL=DEBUG log4j.logger.org.hibernate.transaction=DEBUG 
0
source

All Articles