java - 使用@Transactional时EntityManager.persist()不插入数据

标签 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 应用程序):

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>

这可能出什么问题了?

最佳答案

当你这样做时

EntityManager em = emf.createEntityManager();

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

您可以执行 JB Nizet stated in the comments 操作(好)或使用Spring的ThreadLocal持有者为EntityManager实例。

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

TransactionSynchronizationManager类是

To be used by resource management code but not by typical application code.

关于java - 使用@Transactional时EntityManager.persist()不插入数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19014062/

相关文章:

java - 复制具有关联角色的新用户

Java 或 JavaC 不断提示找不到包或包不存在

java - 在界面中使用@RequestMapping 是不是一个坏主意?

java - ServletContext 属性为空

java - ClassNotFoundException : org. hibernate.ejb.HibernatePersistence 使用 maven 部署

java - 如何使用 hibernate-core-5.2.0.Final.jar 获取所有对象

java - 具有 2 个外键选项的 Hibernate 实体

java - Hibernate 查询语言中的 SQL 子查询

java - Hibernate (hbm) - 合并容器对象后使用 where 子句刷新集合

java - 单元测试目录是否存在 - Junit