使用@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)。