Why does nothing happen when I persist?

I hope I do not ask a question that you have already answered, but I cannot understand my problem ... I explain:

I work with Spring and Hibernate, I have a manager interface and a manager that implements my interface. The manager is as follows:

@Service @Transactional public class ManagerImpl implements Manager { @PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName="Service") private EntityManager em; public void storeHistoricMessage(...params...) throws DBException{ HistoricMessage historicMessage = new HistoricMessage(); // ... initialization of historicMessage try { em.persist(historicMessage); } catch (Exception e){ // process the exception if exists... } } } 

I call my service as follows:

 @Service public class OtherManager { @Autowired private Manager manager; public void storeHistoricMessage(...params...) { manager.storeHistoricMessage(...params...); } } 

My application context is defined as follows:

 <?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:component-scan base-package="package" /> <bean id="JDBCPropertyConfigurer_service" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="properties" ref="JDBCProperties_service" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> </bean> <bean id="JDBCProperties_service" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="location" value="classpath:jdbc.properties" /> </bean> <tx:annotation-driven transaction-manager="transactionManager_service"/> <bean id="transactionManager_service" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory_service" /> </bean> <!-- datasource --> <bean id="dataSource_service" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${database_service.driverClassName}" /> <property name="url" value="${database_service.url}" /> <property name="username" value="${database_service.username}" /> <property name="password" value="${database_service.password}" /> </bean> <!-- JPA config --> <bean id="entityManagerFactory_service" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource_service" /> <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" /> <property name="persistenceUnitName" value="Service" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <!-- <property name="generateDdl" value="${jpa.generateDdl}" /> <property name="showSql" value="${jpa.showSql}" /> <property name="hbm2ddl.auto" value="${jpa.hbm2ddl}" /> --> </bean> </property> </bean> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> </beans> 

And finally, my persistence.xml looks like this:

 <?xml version="1.0" encoding="UTF-8"?> <persistence 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" version="1.0"> <persistence-unit name="Service" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>package.HistoricMessage</class> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" /> <property name="hibernate.archive.autodetection" value="class, hbm" /> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.format_sql" value="false" /> <property name="hibernate.hbm2ddl.auto" value="${hibernate.hbm2ddl.auto}" /> </properties> </persistence-unit> </persistence> 

The problem is that when I save, nothing happens: there is no insertion into the database, there is no error message, there is no exception .... I have done many tests, and maybe some of them help:

  • If I try to return my object using em.find (), I get it ... cache optimization?
  • If I trap him and rename the table to the database after starting the service, I have no error, he is always happy ...
  • If I try em.flush (), it throws an exception because the transaction is not executing ...

Finally, here are the TRACE logs that I see:

 DEBUG 12-01 10:50:01,362 (SessionImpl.java:<init>:220) -opened session at timestamp: 13263618013 DEBUG 12-01 10:50:01,362 (JDBCTransaction.java:begin:54) -begin DEBUG 12-01 10:50:01,362 (ConnectionManager.java:openConnection:421) -opening JDBC connection DEBUG 12-01 10:50:01,363 (DriverManagerDataSource.java:getConnectionFromDriver:163) -Creating new JDBC DriverManager Connection to [jdbc:mysql://databaseurl] DEBUG 12-01 10:50:01,378 (JDBCTransaction.java:begin:59) -current autocommit status: true DEBUG 12-01 10:50:01,379 (JDBCTransaction.java:begin:62) -disabling autocommit TRACE 12-01 10:50:01,380 (JDBCContext.java:afterTransactionBegin:214) -after transaction begin DEBUG 12-01 10:50:01,380 (JpaTransactionManager.java:doBegin:348) -Exposing JPA transaction as JDBC transaction [SimpleConnectionHandle: com.mysql.jdbc.JDBC4Connection@1ff335bb ] TRACE 12-01 10:50:01,381 (TransactionSynchronizationManager.java:bindResource:186) -Bound value [ org.springframework.jdbc.datasource.ConnectionHolder@184c9860 ] for key [ org.springframework.jdbc.datasource.DriverManagerDataSource@6549 9154] to thread [http-8001-Processor5] TRACE 12-01 10:50:01,381 (TransactionSynchronizationManager.java:bindResource:186) -Bound value [ org.springframework.orm.jpa.EntityManagerHolder@4ca7d316 ] for key [org .springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@ 28ce2c57] to thread [http-8001-Processor5] TRACE 12-01 10:50:01,381 (TransactionSynchronizationManager.java:initSynchronization:261) -Initializing transaction synchronization TRACE 12-01 10:50:01,382 (TransactionAspectSupport.java:prepareTransactionInfo:290) -Getting transaction for [package.storeHistoricMessage] storeHistoricMessage (begin of my function) DEBUG 12-01 10:50:01,382 (EntityManagerFactoryUtils.java:doGetTransactionalEntityManager:194) -Opening JPA EntityManager DEBUG 12-01 10:50:01,388 (EntityManagerFactoryUtils.java:doGetTransactionalEntityManager:199) -Registering transaction synchronization for JPA EntityManager DEBUG 12-01 10:50:01,389 (SessionImpl.java:<init>:220) -opened session at timestamp: 13263618013 TRACE 12-01 10:50:01,392 (TransactionSynchronizationManager.java:bindResource:186) -Bound value [ org.springframework.orm.jpa.EntityManagerHolder@69851576 ] for key [org .springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@ 20442c19] to thread [http-8001-Processor5] TRACE 12-01 10:50:01,393 (IdentifierValue.java:isUnsaved:77) -id unsaved-value strategy UNDEFINED TRACE 12-01 10:50:01,394 (AbstractSaveEventListener.java:getEntityState:514) -transient instance of: package.HistoricMessage TRACE 12-01 10:50:01,394 (DefaultPersistEventListener.java:entityIsTransient:124) -saving transient instance DEBUG 12-01 10:50:01,397 (AbstractSaveEventListener.java:saveWithGeneratedId:112) -generated identifier: ***identifier***, using strategy: org.hibernate.id.Assigned TRACE 12-01 10:50:01,397 (AbstractSaveEventListener.java:performSave:153) -saving [package.HistoricMessage#***identifier***] end of my function TRACE 12-01 10:50:01,399 (TransactionAspectSupport.java:commitTransactionAfterReturning:319) -Completing transaction for [package.storeHistoricMessage] TRACE 12-01 10:50:01,400 (AbstractPlatformTransactionManager.java:triggerBeforeCommit:903) -Triggering beforeCommit synchronization TRACE 12-01 10:50:01,400 (AbstractPlatformTransactionManager.java:triggerBeforeCompletion:916) -Triggering beforeCompletion synchronization TRACE 12-01 10:50:01,401 (TransactionSynchronizationManager.java:doUnbindResource:232) -Removed value [ org.springframework.orm.jpa.EntityManagerHolder@69851576 ] for key [org .springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@ 20442c19] from thread [http-8001-Processor5] DEBUG 12-01 10:50:01,401 (EntityManagerFactoryUtils.java:closeEntityManager:313) -Closing JPA EntityManager TRACE 12-01 10:50:01,401 (SessionImpl.java:close:273) -closing session TRACE 12-01 10:50:01,402 (ConnectionManager.java:cleanup:375) -connection already null in cleanup : no action DEBUG 12-01 10:50:01,402 (AbstractPlatformTransactionManager.java:processCommit:730) -Initiating transaction commit DEBUG 12-01 10:50:01,402 (JpaTransactionManager.java:doCommit:451) -Committing JPA transaction on EntityManager [ org.hibernate.ejb.EntityManagerImpl@27b71c12 ] DEBUG 12-01 10:50:01,403 (JDBCTransaction.java:commit:103) -commit TRACE 12-01 10:50:01,403 (SessionImpl.java:managedFlush:337) -automatically flushing session TRACE 12-01 10:50:01,403 (JDBCContext.java:beforeTransactionCompletion:205) -before transaction completion TRACE 12-01 10:50:01,404 (SessionImpl.java:beforeTransactionCompletion:393) -before transaction completion DEBUG 12-01 10:50:01,405 (JDBCTransaction.java:toggleAutoCommit:193) -re-enabling autocommit DEBUG 12-01 10:50:01,406 (JDBCTransaction.java:commit:116) -committed JDBC Connection TRACE 12-01 10:50:01,407 (JDBCContext.java:afterTransactionCompletion:219) -after transaction completion DEBUG 12-01 10:50:01,407 (ConnectionManager.java:aggressiveRelease:404) -aggressively releasing JDBC connection DEBUG 12-01 10:50:01,408 (ConnectionManager.java:closeConnection:441) -releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)] TRACE 12-01 10:50:01,408 (SessionImpl.java:afterTransactionCompletion:422) -after transaction completion TRACE 12-01 10:50:01,409 (AbstractPlatformTransactionManager.java:triggerAfterCommit:929) -Triggering afterCommit synchronization TRACE 12-01 10:50:01,409 (AbstractPlatformTransactionManager.java:triggerAfterCompletion:945) -Triggering afterCompletion synchronization TRACE 12-01 10:50:01,410 (TransactionSynchronizationManager.java:clearSynchronization:315) -Clearing transaction synchronization TRACE 12-01 10:50:01,410 (TransactionSynchronizationManager.java:doUnbindResource:232) -Removed value [ org.springframework.orm.jpa.EntityManagerHolder@4ca7d316 ] for key [org .springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@ 28ce2c57] from thread [http-8001-Processor5] TRACE 12-01 10:50:01,410 (TransactionSynchronizationManager.java:doUnbindResource:232) -Removed value [org.spri ngframework.jdbc.datasource.ConnectionHolder@184c9860 ] for key [ org.springframework.jdbc.datasource.DriverManagerDataSource@6549 9154] from thread [http-8001-Processor5] DEBUG 12-01 10:50:01,411 (JpaTransactionManager.java:doCleanupAfterCompletion:534) -Closing JPA EntityManager [ org.hibernate.ejb.EntityManagerImpl@27b71c12 ] after transaction DEBUG 12-01 10:50:01,411 (EntityManagerFactoryUtils.java:closeEntityManager:313) -Closing JPA EntityManager TRACE 12-01 10:50:01,411 (SessionImpl.java:close:273) -closing session TRACE 12-01 10:50:01,412 (ConnectionManager.java:cleanup:375) -connection already null in cleanup : no action 

Thank you for help!

Edit: I'm sorry, I realized what happened and you could not find it because I really simplified the architecture of my project and I did not tell you the reason: In this project, I have several application context files and several data sources, so I use it several times .... And with Spring 2.5 you can only have one! So I cannot use transactions in my second service ... To solve this problem, I used aop as follows:

 <tx:advice id="txAdviceSelfCare" transaction-manager="transactionManager_service"> <!-- the transactional semantics... --> <tx:attributes> <!-- other methods use the default transaction settings (see below) --> <tx:method name="*" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="ServiceManagerOperations" expression="execution(* package.ServiceManager.*(..))" /> <aop:advisor advice-ref="txAdviceService" pointcut-ref="ServiceManagerOperations" /> </aop:config> <!-- a PlatformTransactionManager is still required --> <bean id="transactionManager_service" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory_service" /> </bean> 

Thank you all for your help!

+4
source share
5 answers

Could you try to check what is really happening in your database? Try activating the logging services in this database, and if you have such a tool to sniff the network traffic between your Java code and the database server ... this can be useful ... You can ask your JPA level to show the SQL generated file, it can give you interesting data ... My 2 pieces are Jerome

+1
source

Modify your catch block to do something and see what it prints.

  try { em.persist(historicMessage); } catch (Exception e){ e.printStackTrace(); // use a logger if available } 

You can also change the property below to true to see what happens.

 <property name="hibernate.show_sql" value="true" /> 

Also make it a habit to track I / O of methods using an appropriate logging structure such as SLF4J .

0
source

Note that the actual insertion is not performed in the em.persist statement, since the call is transactional, so your try / catch will not do anything at all. The actual save is saved when the transaction completes, when the service level call ends (after returning from your method). This knowledge is crucial in the persistence of debugging.

0
source

Check the database in which you look at the details. The magazine clearly states that the fixation is complete ..

DEBUG 12-01 10:50:01,403 (JDBCTransaction.java:commit:103) -commit TRACE 12-01 10:50:01,403 (SessionImpl.java:managedFlush:337) -automatically flushing session TRACE 12-01 10:50:01,403 (JDBCContext.java:beforeTransactionCompletion:205) -before transaction completion TRACE 12-01 10:50:01,404 (SessionImpl.java:beforeTransactionCompletion:393) -before transaction completion DEBUG 12-01 10:50:01,405 (JDBCTransaction.java:toggleAutoCommit:193) -re-enabling autocommit DEBUG 12-01 10:50:01,406 (JDBCTransaction.java:commit:116) -committed JDBC Connection

0
source

Put a method call in a try catch

 public void storeHistoricMessage(...params...) { try { manager.storeHistoricMessage(...params...); } catch (Exception e) { e.printStackTrace(); // use a logger if available } } 

Data should be stored at the end of the manager.storeHistoricMessage method call (through the transaction management proxy), and not when em.persist is called. You can also try em.flush:

 try { em.persist(historicMessage); em.flush(); //force DB insert }... 

It looks like you are not seeing an exception that is thrown at something, probably by the transaction manager.

0
source

Source: https://habr.com/ru/post/1390606/


All Articles