使用@Transactional时,EntityManager.persist()不会插入数据

最近我将项目设置更改为使用Spring进行声明式事务处理。 或者至少我想。 当我调用persist ,不执行任何INSERT语句。

我为Spring ORM启用了TRACE日志级别,这就是我得到的:

 DEBUG JpaTransactionManager: Creating new transaction with name [albw.service.TransactionTestService.doServiceMethod]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' DEBUG JpaTransactionManager: Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@28a7bd7a] for JPA transaction DEBUG BasicResourcePool: trace com.mchange.v2.resourcepool.BasicResourcePool@10ea443f [managed: 5, unused: 4, excluded: 0] (eg com.mchange.v2.c3p0.impl.NewPooledConnection@1ca37c6a) DEBUG JpaTransactionManager: Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@55d4ee7e] TRACE TransactionSynchronizationManager: Bound value [org.springframework.jdbc.datasource.ConnectionHolder@e75be38] for key [com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1bqonb88xo1f3w01izopd3|638bd7f1, DEBUGUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> oracle.jdbc.driver.OracleDriver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1bqonb88xo1f3w01izopd3|638bd7f1, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:oracle:thin:@bf-ws-wpssrv01:1521:xe, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 300, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]] to thread [main] TRACE TransactionSynchronizationManager: Bound value [org.springframework.orm.jpa.EntityManagerHolder@4ea7ae01] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@6290ebfe] to thread [main] TRACE TransactionSynchronizationManager: Initializing transaction synchronization TRACE TransactionInterceptor: Getting transaction for [albw.service.TransactionTestService.doServiceMethod] DEBUG BasicResourcePool: trace com.mchange.v2.resourcepool.BasicResourcePool@10ea443f [managed: 5, unused: 3, excluded: 0] (eg com.mchange.v2.c3p0.impl.NewPooledConnection@1ca37c6a) Hibernate: select wpappalbw_w.hibernate_sequence.nextval from dual DEBUG BasicResourcePool: trace com.mchange.v2.resourcepool.BasicResourcePool@10ea443f [managed: 5, unused: 3, excluded: 0] (eg com.mchange.v2.c3p0.impl.NewPooledConnection@1ca37c6a) DEBUG TransactionTestService: After persist TRACE TransactionInterceptor: Completing transaction for [albw.service.TransactionTestService.doServiceMethod] TRACE JpaTransactionManager: Triggering beforeCommit synchronization TRACE JpaTransactionManager: Triggering beforeCompletion synchronization DEBUG JpaTransactionManager: Initiating transaction commit DEBUG JpaTransactionManager: Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@28a7bd7a] DEBUG BasicResourcePool: trace com.mchange.v2.resourcepool.BasicResourcePool@10ea443f [managed: 5, unused: 4, excluded: 0] (eg com.mchange.v2.c3p0.impl.NewPooledConnection@1ca37c6a) TRACE JpaTransactionManager: Triggering afterCommit synchronization TRACE JpaTransactionManager: Triggering afterCompletion synchronization TRACE TransactionSynchronizationManager: Clearing transaction synchronization TRACE TransactionSynchronizationManager: Removed value [org.springframework.orm.jpa.EntityManagerHolder@4ea7ae01] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@6290ebfe] from thread [main] TRACE TransactionSynchronizationManager: Removed value [org.springframework.jdbc.datasource.ConnectionHolder@e75be38] for key [com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1bqonb88xo1f3w01izopd3|638bd7f1, DEBUGUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> oracle.jdbc.driver.OracleDriver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1bqonb88xo1f3w01izopd3|638bd7f1, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:oracle:thin:@bf-ws-wpssrv01:1521:xe, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 300, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]] from thread [main] DEBUG JpaTransactionManager: Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@28a7bd7a] after transaction DEBUG EntityManagerFactoryUtils: Closing JPA EntityManager 

这是我的代码(Java SE Application):

 public static void main(String[] args) { // context is my ApplicationContext TransactionTestService t = context.getBean(TransactionTestService.class); t.doServiceMethod(); } 

TransactionTestService.java:

 @Service @Transactional(readOnly=false) public class TransactionTestService { @Autowired private EntityManagerFactory emf; @Transactional(readOnly=false, propagation=Propagation.REQUIRED) public void doServiceMethod() { EntityManager em = emf.createEntityManager(); ParentSupplier p = new ParentSupplier(); p.setName("Test"); em.persist(p); logger.debug("After persist"); } } 

ParentSupplier.java:

 @Entity public class ParentSupplier { @Id @GeneratedValue private Long id; @Column(nullable=false, length=500) private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } 

我的beans.xml:

         albw.model       validate org.hibernate.dialect.Oracle10gDialect                    

它可能有什么问题?

当你这样做

 EntityManager em = emf.createEntityManager(); 

您将获得与@Transactional代理创建的EntityManager不同的EntityManager

您可以执行JB Nizet在注释中所述的内容 (好),也可以使用Spring的ThreadLocal holder来实现EntityManager实例。

 EntityManagerHolder holder = TransactionSynchronizationManager.getResource(emf); EntityManager em = holder.getEntityManager(); 

TransactionSynchronizationManager类是

由资源管理代码使用,但不是由典型的应用程序代码使用。

在测试类的顶部添加@TransactionConfiguration(defaultRollback = false)。