简体   繁体   English

Spring Boot休眠没有事务进行中

[英]Spring boot hibernate no transaction is in progress

I'm using spring boot and it perfectly makes me entity manager. 我使用的是Spring Boot,它使我成为实体经理。 And I decided to test getting session factory from the entity manager and to use it for an example. 我决定测试从实体管理器获取会话工厂并将其用作示例。 But I get the next problem: javax.persistence.TransactionRequiredException: no transaction is in progress 但是我遇到了下一个问题: javax.persistence.TransactionRequiredException: no transaction is in progress

properties 属性

spring.datasource.url= jdbc:postgresql://localhost:5432/ring
spring.datasource.username=postgres
spring.datasource.password=root

spring.jpa.show-sql = false
spring.jpa.properties.hibernate.format_sql=false

#Note: The last two properties on the code snippet above were added to suppress an annoying exception
# that occurs when JPA (Hibernate) tries to verify PostgreSQL CLOB feature.
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false

spring.jpa.properties.hibernate.current_session_context_class = org.springframework.orm.hibernate5.SpringSessionContext

service class 服务等级

package kz.training.springrest.service;

import kz.training.springrest.entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;

@Service
public class UserService {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    public void insertUser(User user) {
        SessionFactory sessionFactory = entityManager.unwrap(Session.class).getSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        session.save(user);
    }

}

runner 跑步者

package kz.training.springrest.run;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication
@EntityScan("kz.training.springrest.entity")
@EnableTransactionManagement
@ComponentScan(basePackages="kz.training.springrest")
public class SpringrestApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringrestApplication.class, args);
    }
}

Do you have any ideas how to solve it? 您有任何解决方法的想法吗?

I don't quite understand why you're making your service method so unnecessarily complex. 我不太明白为什么您要使服务方法变得如此不必要地复杂。 You should simply be able to do it this way 您应该只可以这样做

@Transactional
public void insertUser(User user) {
  entityManager.persist( user );
}

If there are points where you need access to the native Hibernate Session you can simply unwrap and use the Session directly like this: 如果有些地方需要访问本机Hibernate Session ,则可以像下面这样直接打开和使用Session

@Transactional
public void doSomethingFancyWithASession() {
  Session session = entityManager.unwrap( Session.class );
  // use session as needed
}

The notion here is that Spring provides you an already functional EntityManager instance by you using the @PersistenceContext annotation. 这里的概念是Spring通过使用@PersistenceContext批注为您提供了一个已经正常运行的EntityManager实例。 That instance will safely be usable by the current thread your spring bean is being executed within. 该实例将在您的spring bean正在其中执行的当前线程中安全地使用。

Secondly, by using @Transactional , this causes Spring's transaction management to automatically make sure that the EntityManager is bound to a transaction, whether that is a RESOURCE_LOCAL or JTA transaction is based on your environment configuration. 其次,通过使用@Transactional ,这将导致Spring的事务管理自动确保EntityManager绑定到事务,无论是RESOURCE_LOCAL还是JTA事务都是基于您的环境配置。

You're running into your problem because of the call to #getCurrentSession() . 由于调用#getCurrentSession() ,您#getCurrentSession()问题。

What is happening is Spring creates the EntityManager , then inside your method when you make the call to #getCurrentSession() , you're asking Hibernate to create a second session that is not bound to the transaction started by your @Transactional annotation. 发生的事情是Spring创建了EntityManager ,然后在您的方法内部调用#getCurrentSession() ,您要让Hibernate创建第二个会话,该会话未绑定到由@Transactional注释启动的事务。 In short its essentially akin to the following: 简而言之,它基本上类似于以下内容:

EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Session aNewSession = entityManager.unwrap( Session.class )
  .getFactory()
  .getCurrentSession();
// at this point entityManager is scoped to a transaction
// aNewSession is not scoped to any transaction
// this also likely uses 2 connections to the database which is a waste

So follow the paradigm I mention above and you should no longer run into the problem. 因此,按照我上面提到的范例进行操作,您就不再遇到问题了。 You should never need to call #getCurrentSession() or #openSession() in a Spring environment if you're properly allowing Spring to inject your EntityManager instance for you. 如果您正确地允许Spring为您注入EntityManager实例,则永远不需要在Spring环境中调用#getCurrentSession()#openSession()

I have same your error, when I deploy my spring boot app to WebLogic Server. 将Spring Boot应用程序部署到WebLogic Server时,我也遇到同样的错误。 (Even It works fine if I run it directly via Eclipse (Or deploy to Tomcat) ). (即使我直接通过Eclipse运行它(或部署到Tomcat),它也可以正常工作)。

I solved the problem by adding @EnableTransactionManagement to UserService. 我通过将@EnableTransactionManagement添加到UserService解决了该问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring 使用 2 个数据源启动“没有正在进行的事务” - Spring boot "no transaction is in progress" with 2 datasources 无法创建事务[Spring Boot +休眠] - Can't Create Transaction [Spring Boot + Hibernate] Spring 引导数据 Hibernate 事务管理器 - Spring Boot Data Hibernate Transaction Manager Hibernate JPA和Spring javax.persistence.TransactionRequiredException:没有事务正在进行中 - Hibernate JPA and Spring javax.persistence.TransactionRequiredException: no transaction is in progress Hibernate + Spring:javax.persistence.TransactionRequiredException:没有正在进行的事务 - Hibernate + Spring: javax.persistence.TransactionRequiredException: no transaction is in progress 在 Spring 启动应用程序中获取“javax.persistence.TransactionRequiredException:没有正在进行的事务” - Getting “javax.persistence.TransactionRequiredException: no transaction is in progress” in Spring Boot Application 无法在 hibernate spring 引导中的单个事务中保存父子节点 - Unable to save parent and child in single transaction in hibernate spring boot Spring JPA 没有正在进行的交易 - Spring JPA no transaction is in progress Spring JPA:没有正在进行的事务 - Spring JPA: no transaction is in progress 即使应用了事务拦截器,“ TransactionRequiredException:没有事务正在进行中”-hibernate-5和spring-4.3 - “TransactionRequiredException: no transaction is in progress” even when transaction interceptor is applied - hibernate-5 and spring-4.3
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM