Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring Boot:javax.persistence.TransactionRequiredException:使用@Transactional注释时执行更新/删除查询_Java_Spring Boot_Hibernate_Transactions - Fatal编程技术网

Spring Boot:javax.persistence.TransactionRequiredException:使用@Transactional注释时执行更新/删除查询

Spring Boot:javax.persistence.TransactionRequiredException:使用@Transactional注释时执行更新/删除查询,java,spring-boot,hibernate,transactions,Java,Spring Boot,Hibernate,Transactions,我正在研究SpringBoot(v1.5.22.RELEASE)和Hibernate5.4.20.Final[pom.xml附件bellow]。也尝试了SpringBoot(v2.2.2),但我得到了相同的错误 在我的项目中,数据库是动态的。根据请求,数据库将被更改 我正在使用SessionBuilderImpl类设置数据库并获取当前会话 尝试更新表[使用HQL或NativeSQL]时,会引发以下异常: ERROR AppDeploymentHistoryDaoImpl ERROR WHILE

我正在研究SpringBoot(v1.5.22.RELEASE)和Hibernate5.4.20.Final[pom.xml附件bellow]。也尝试了SpringBoot(v2.2.2),但我得到了相同的错误

在我的项目中,数据库是动态的。根据请求,数据库将被更改

我正在使用SessionBuilderImpl类设置数据库并获取当前会话

尝试更新表[使用HQL或NativeSQL]时,会引发以下异常:

ERROR AppDeploymentHistoryDaoImpl ERROR WHILE UPDATING APP DEPLOYMENT HISTORY STATUS { SET `is_current_exec` = 0 } IN DATABASE { AppDeploymentHistoryDaoImpl.updateAllStatus }javax.persistence.TransactionRequiredException: Executing an update/delete query
        at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:413)
        at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1608)
        at com.testcompany.app.fw.amt.entity.daoimpl.AppDeploymentHistoryDaoImpl.updateAllStatus(AppDeploymentHistoryDaoImpl.java:58)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
        at com.sun.proxy.$Proxy69.updateAllStatus(Unknown Source)
        at com.testcompany.app.fw.amt.entity.serviceimpl.AppDeploymentHistoryServiceImpl.updateAllStatus(AppDeploymentHistoryServiceImpl.java:55)
        at com.testcompany.app.fw.amt.entity.serviceimpl.AppDeploymentHistoryServiceImpl$$FastClassBySpringCGLIB$$2b450460.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:283)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
        at com.testcompany.app.fw.amt.entity.serviceimpl.AppDeploymentHistoryServiceImpl$$EnhancerBySpringCGLIB$$8b3a1110.updateAllStatus(<generated>)
        at com.testcompany.app.fw.amt.core.AppHandler.resetAppDeploymentHsitoryStatus(AppHandler.java:121)
        at com.testcompany.app.fw.amt.core.AppHandler.setBasicSetup(AppHandler.java:80)
        at com.testcompany.app.fw.amt.core.AppUninstallInitiator.setBasicSetup(AppUninstallInitiator.java:45)
        at com.testcompany.app.fw.amt.core.AppUninstallInitiator$$FastClassBySpringCGLIB$$77c48f3c.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:667)
        at com.testcompany.app.fw.amt.core.AppUninstallInitiator$$EnhancerBySpringCGLIB$$69685b24.setBasicSetup(<generated>)
        at com.testcompany.app.fw.amt.rmq.UndeploymentQueueConsumer.init(UndeploymentQueueConsumer.java:87)
        at com.testcompany.app.fw.amt.rmq.UndeploymentQueueConsumer.handleDelivery(UndeploymentQueueConsumer.java:101)
        at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149)
        at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)


AppDeploymentHistoryServiceImpl.java


@Configuration
@EnableTransactionManagement
public class HibernateConfig {
   @Autowired
   private DbProperties dbProperties;

  @Bean
  public LocalSessionFactoryBean hibernateSessionFactory() {
    LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
    sessionFactoryBean.setDataSource(dataSource());
    sessionFactoryBean.setAnnotatedPackages("com.testcompany.app.fw.amt.*");
    sessionFactoryBean.setPackagesToScan("com.testcompany.app.fw.amt.*");
    sessionFactoryBean.setHibernateProperties(additionalProperties());
    return sessionFactoryBean;
   }
   @Bean
   public PlatformTransactionManager hibernateTransactionManager() {
     HibernateTransactionManager transactionManager = new HibernateTransactionManager();
     transactionManager.setSessionFactory(hibernateSessionFactory().getObject());
     transactionManager.setDataSource(dataSource());
     return transactionManager;
   }
    @Bean
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl(String.format(AppConstants.CONNECTION_URL, dbProperties.getDbHost(), dbProperties.getDbPort()));
        dataSource.setUsername(dbProperties.getDbUser());
        dataSource.setPassword(dbProperties.getDbPassword());
        dataSource.setMaximumPoolSize(30);
        dataSource.setMinimumIdle(30);
        dataSource.setConnectionTestQuery("SELECT 1");
        return dataSource; 
    }
    public Properties additionalProperties() {
        Properties settings = new Properties();
        settings.put(Environment.DIALECT, "org.hibernate.dialect.MariaDB53Dialect");
        settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
        return settings;
    }

}
 @Override
 @Transactional
 public void updateAllStatus(String clientDbName) throws ToolException {
      try{
           appDeploymentHistoryDao.updateAllStatus(clientDbName);
        }catch(HibernateException he){
            logger.error("***** <<< ERROR IN AppDeploymentHistoryServiceImpl.updateAllStatus >>> *****" , he);
        }
    }
    @Override
    public void updateAllStatus(String clientDbName) {
        try {
            Session session = sessionBuilder.getClientSession(clientDbName);
            Query query = session.createSQLQuery("UPDATE `app_deployement_history` SET `is_current_exec` = 0 ");
            query.executeUpdate();
        } catch (Exception ex) {
            logger.error("ERROR WHILE UPDATING APP DEPLOYMENT HISTORY STATUS { SET `is_current_exec` = 0 } IN DATABASE { AppDeploymentHistoryDaoImpl.updateAllStatus }" + ExceptionUtils.getFullStackTrace(ex));
        }
    }

@Component
public class SessionBuilderImpl implements SessionBuilder {

    private static final Logger LOGGER = LoggerFactory.getLogger(SessionBuilderImpl.class);
    private static final String EXECPTION_MSG = "Error while exchanging database in session : Super amdin ";
    @Autowired
    private SessionFactory sessionFactory;


    @Override
    public Session getClientSession(String dbName) throws HibernateException {
        Session currentSession = sessionFactory.getCurrentSession();
        try {
            Connection connection = sessionFactory.getSessionFactoryOptions().getServiceRegistry().
                                                   getService(ConnectionProvider.class).getConnection();
            connection.setCatalog(dbName);
            org.hibernate.SessionBuilder hibernateSessionBuilder = sessionFactory.withOptions();
            currentSession = hibernateSessionBuilder.connection(connection).openSession();
        } catch (SQLException ex) {
            LOGGER.error("***** <<< HIBERNATE EXCEPTION : IN HIBERNATE_CONFIG : getSessionByDb(String dbName) >>> *****");
        }
        return currentSession;
    }

    @Override
    public Connection getCurrentConnection() throws HibernateException {
        Session currentSession = sessionFactory.getCurrentSession();
        Connection connection = ((SessionImpl) currentSession).connection();
        return connection;
    }
}

SessionBuilderImpl.java


@Configuration
@EnableTransactionManagement
public class HibernateConfig {
   @Autowired
   private DbProperties dbProperties;

  @Bean
  public LocalSessionFactoryBean hibernateSessionFactory() {
    LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
    sessionFactoryBean.setDataSource(dataSource());
    sessionFactoryBean.setAnnotatedPackages("com.testcompany.app.fw.amt.*");
    sessionFactoryBean.setPackagesToScan("com.testcompany.app.fw.amt.*");
    sessionFactoryBean.setHibernateProperties(additionalProperties());
    return sessionFactoryBean;
   }
   @Bean
   public PlatformTransactionManager hibernateTransactionManager() {
     HibernateTransactionManager transactionManager = new HibernateTransactionManager();
     transactionManager.setSessionFactory(hibernateSessionFactory().getObject());
     transactionManager.setDataSource(dataSource());
     return transactionManager;
   }
    @Bean
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl(String.format(AppConstants.CONNECTION_URL, dbProperties.getDbHost(), dbProperties.getDbPort()));
        dataSource.setUsername(dbProperties.getDbUser());
        dataSource.setPassword(dbProperties.getDbPassword());
        dataSource.setMaximumPoolSize(30);
        dataSource.setMinimumIdle(30);
        dataSource.setConnectionTestQuery("SELECT 1");
        return dataSource; 
    }
    public Properties additionalProperties() {
        Properties settings = new Properties();
        settings.put(Environment.DIALECT, "org.hibernate.dialect.MariaDB53Dialect");
        settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
        return settings;
    }

}
 @Override
 @Transactional
 public void updateAllStatus(String clientDbName) throws ToolException {
      try{
           appDeploymentHistoryDao.updateAllStatus(clientDbName);
        }catch(HibernateException he){
            logger.error("***** <<< ERROR IN AppDeploymentHistoryServiceImpl.updateAllStatus >>> *****" , he);
        }
    }
    @Override
    public void updateAllStatus(String clientDbName) {
        try {
            Session session = sessionBuilder.getClientSession(clientDbName);
            Query query = session.createSQLQuery("UPDATE `app_deployement_history` SET `is_current_exec` = 0 ");
            query.executeUpdate();
        } catch (Exception ex) {
            logger.error("ERROR WHILE UPDATING APP DEPLOYMENT HISTORY STATUS { SET `is_current_exec` = 0 } IN DATABASE { AppDeploymentHistoryDaoImpl.updateAllStatus }" + ExceptionUtils.getFullStackTrace(ex));
        }
    }

@Component
public class SessionBuilderImpl implements SessionBuilder {

    private static final Logger LOGGER = LoggerFactory.getLogger(SessionBuilderImpl.class);
    private static final String EXECPTION_MSG = "Error while exchanging database in session : Super amdin ";
    @Autowired
    private SessionFactory sessionFactory;


    @Override
    public Session getClientSession(String dbName) throws HibernateException {
        Session currentSession = sessionFactory.getCurrentSession();
        try {
            Connection connection = sessionFactory.getSessionFactoryOptions().getServiceRegistry().
                                                   getService(ConnectionProvider.class).getConnection();
            connection.setCatalog(dbName);
            org.hibernate.SessionBuilder hibernateSessionBuilder = sessionFactory.withOptions();
            currentSession = hibernateSessionBuilder.connection(connection).openSession();
        } catch (SQLException ex) {
            LOGGER.error("***** <<< HIBERNATE EXCEPTION : IN HIBERNATE_CONFIG : getSessionByDb(String dbName) >>> *****");
        }
        return currentSession;
    }

    @Override
    public Connection getCurrentConnection() throws HibernateException {
        Session currentSession = sessionFactory.getCurrentSession();
        Connection connection = ((SessionImpl) currentSession).connection();
        return connection;
    }
}


@组成部分
公共类SessionBuilderImpl实现SessionBuilder{
私有静态最终记录器Logger=LoggerFactory.getLogger(SessionBuilderImpl.class);
private static final String EXECPTION_MSG=“在会话中交换数据库时出错:Super amdin”;
@自动连线
私人会话工厂会话工厂;
@凌驾
公共会话getClientSession(字符串dbName)引发HibernateeException{
会话currentSession=sessionFactory.getCurrentSession();
试一试{
连接连接=sessionFactory.getSessionFactoryOptions().getServiceRegistry()。
getService(ConnectionProvider.class).getConnection();
connection.setCatalog(dbName);
org.hibernate.SessionBuilder hibernateSessionBuilder=sessionFactory.withOptions();
currentSession=hibernateSessionBuilder.connection(connection).openSession();
}catch(SQLException-ex){
LOGGER.error(“******>*******”);
}
返回当前会话;
}
@凌驾
公共连接getCurrentConnection()引发HibernateeException{
会话currentSession=sessionFactory.getCurrentSession();
连接连接=((SessionImpl)currentSession).Connection();
回路连接;
}
}
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.testcompany.app.fw.amt</groupId>
    <artifactId>AMTTool</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.22.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.20.Final</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
        </dependency>
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-aop</artifactId>  
        </dependency>
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.skyscreamer</groupId>
            <artifactId>jsonassert</artifactId>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1-rc1</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>test</scope>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.2.2</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>javaxt</groupId>
            <artifactId>javaxt-core</artifactId>
            <version>1.7.8</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>maven-restlet</id>
            <name>Public online Restlet repository</name>
            <url>https://maven.restlet.talend.com/</url>
        </repository>
        <repository>
            <id>jspresso-repository</id>
            <url>http://repository.jspresso.org/maven2</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <name>AMTTool</name>
</project>

4.0.0
com.testcompany.app.fw.amt
阿姆托
1
罐子
UTF-8
1.8
1.8
1.8
org.springframework.boot
spring启动程序父级
1.5.22.发布
com.rabbitmq
amqp客户端
罐子
org.springframework
德克萨斯州春季
罐子
org.springframework
春季甲虫
罐子
org.hibernate
冬眠核心
5.4.20.最终版本
罐子
org.mariadb.jdbc
mariadb java客户端
org.springframework.boot
弹簧启动机aop
com.zaxxer
希卡里普
3.2.0
公地io
公地io
2.6
罐子
net.lingala.zip4j
zip4j
1.3.2
com.fasterxml.jackson.core
杰克逊数据绑定
罐子
com.fasterxml.jackson.core
杰克逊注释
com.fasterxml.jackson.core
杰克逊核心
天空尖叫者
杰索纳塞特
罐子
org.apache.httpcomponents
httpcore
罐子
commons httpclient
commons httpclient
3.1-rc1
罐子
org.apache.logging.log4j
log4japi
罐子
公地郎
公地郎
2.6
罐子
爪哇
javaeewebapi
7
测试
罐子
com.squareup.okhttp3
okhttp
4.2.2
公共dbcp
公共dbcp
1.4
javaxt
javaxt内核
1.7.8
org.springframework.boot
springbootmaven插件
maven restlet
公共在线Restlet存储库
https://maven.restlet.talend.com/
jspresso存储库
http://repository.jspresso.org/maven2
真的
假的
阿姆托

我非常怀疑,“保存”和其他案例在这里也能起作用,除非您在这里发布了其他代码

代码的问题在于,您正在手动创建另一个会话,与事务管理器绑定的会话(spring正在管理)没有意识到这一点,因此您的更改不会反映出来

因为,这里的update/delete正在修改本机查询,所以hibernate抛出错误,因为它找不到任何与之关联的事务

TL;博士 为了验证它,我做了一些挖掘,并创建了与您发布的相同的配置

@Configuration
@EnableConfigurationProperties(JpaProperties.class)
@EnableTransactionManagement
class CustomJpaConfiguration {
    @Autowired
    private JpaProperties jpaProperties;

    @Bean
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl(jpaProperties.getDatasource().getUrl());
        dataSource.setDriverClassName(jpaProperties.getDatasource().getDriver());
        dataSource.setUsername(jpaProperties.getDatasource().getUsername());
        dataSource.setPassword(jpaProperties.getDatasource().getPassword());
        dataSource.setConnectionTestQuery("select 1");
        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean localSessionFactoryBean() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan("com.example.jpa.model");
        sessionFactory.setHibernateProperties(additionalProperties());
        return sessionFactory;
    }

    private Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", jpaProperties.getDialect());
        properties.setProperty("hibernate.show_sql", "" + jpaProperties.isShowSql());
        properties.setProperty("hibernate.hbm2ddl.auto",
                jpaProperties.getDdlMode() == null ? "none" : jpaProperties.getDdlMode());
        return properties;
    }


    @Bean
    public PlatformTransactionManager transactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(localSessionFactoryBean().getObject());
        transactionManager.setDataSource(dataSource());
        return transactionManager;
    }
}
首先,我检查了sessionFactory.getCurrentSession()是否给出了相同的错误

因此,我创建了一个小实体类

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    @CreationTimestamp
    @Column(name = "created_on", nullable = false, updatable = false)
    private LocalDateTime createdOn;

    @UpdateTimestamp
    @Column(name = "updated_on", nullable = false)
    private LocalDateTime updatedOn;

    @Version
    private int version;

    @OneToMany(mappedBy = "user",fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
    private final Set<Role> roles = new HashSet<>();
    
    // Ignoring getters and setters
}
您可以清楚地看到insert语句正在执行,我检查了返回的
id
,它是非空的

现在,我使用了您发布的会话生成器代码,并使用该代码创建了日志

2021-04-09 22:45:42.300 TRACE 63184 --- [           main] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.jdbc.datasource.ConnectionHolder@60ef30b1] for key [HikariDataSource (HikariPool-1)] to thread [main]
2021-04-09 22:45:42.301 TRACE 63184 --- [           main] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.orm.hibernate5.SessionHolder@3f40568e] for key [org.hibernate.internal.SessionFactoryImpl@3436d3d7] to thread [main]
2021-04-09 22:45:42.301 TRACE 63184 --- [           main] .s.t.s.TransactionSynchronizationManager : Initializing transaction synchronization
2021-04-09 22:45:42.301 TRACE 63184 --- [           main] o.s.t.i.TransactionInterceptor           : Getting transaction for [com.example.jpa.service.UserService.addUser]
2021-04-09 22:45:42.332 TRACE 63184 --- [           main] o.s.t.i.TransactionInterceptor           : Completing transaction for [com.example.jpa.service.UserService.addUser]
2021-04-09 22:45:42.335 TRACE 63184 --- [           main] .s.t.s.TransactionSynchronizationManager : Clearing transaction synchronization
2021-04-09 22:45:42.335 TRACE 63184 --- [           main] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.orm.hibernate5.SessionHolder@3f40568e] for key [org.hibernate.internal.SessionFactoryImpl@3436d3d7] from thread [main]
2021-04-09 22:45:42.335 TRACE 63184 --- [           main] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.jdbc.datasource.ConnectionHolder@60ef30b1] for key [HikariDataSource (HikariPool-1)] from thread [main]
请注意,在这两个日志中,事务同步管理器启动和关闭事务,但在以前的日志中,事务同步管理器发出insert语句,而在以后的日志中,事务同步管理器不会发出insert语句,因为您使用
连接
对象再次创建了会话,事务管理器从未看到它

现在,如果我用