最近我将项目设置更改为使用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] (e.g. 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] (e.g. 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] (e.g. 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] (e.g. 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:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-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/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<util:properties id="deployment" location="classpath:deployment.properties" />
<context:component-scan base-package="albw" />
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>albw.model</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
<property name="jdbcUrl" value="jdbc:oracle:thin:@db-server:1521:xe" />
<property name="user" value="albw" />
<property name="password" value="xxx" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxIdleTime" value="300" />
</bean>
</beans>
它可能有什么问题?
答案 0 :(得分:2)
当你这样做时
EntityManager em = emf.createEntityManager();
您获得的EntityManager
与@Transactional
代理创建的ThreadLocal
不同。
您可以执行JB Nizet stated in the comments(好)或使用Spring EntityManager
EntityManagerHolder holder = TransactionSynchronizationManager.getResource(emf);
EntityManager em = holder.getEntityManager();
个实例的持有者。
{{1}}
TransactionSynchronizationManager
类是
由资源管理代码使用,但不是由典型应用程序使用 代码。
答案 1 :(得分:0)
在测试类的顶部添加@TransactionConfiguration(defaultRollback = false)。