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

时间:2013-09-25 19:55:51

标签: java spring hibernate jpa transactions

最近我将项目设置更改为使用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>

它可能有什么问题?

2 个答案:

答案 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)。