首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Spring boot休眠没有正在进行的事务

Spring boot休眠没有正在进行的事务
EN

Stack Overflow用户
提问于 2018-06-02 03:37:25
回答 2查看 13.4K关注 0票数 8

我使用的是spring boot,它完美地让我成为了实体管理器。我决定测试从实体管理器获取会话工厂,并将其用作示例。但是我遇到了下一个问题:javax.persistence.TransactionRequiredException: no transaction is in progress

属性

代码语言:javascript
复制
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

服务类

代码语言:javascript
复制
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);
    }

}

跑步者

代码语言:javascript
复制
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);
    }
}

你有什么办法解决这个问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-02 12:27:46

我不太明白为什么你要让你的服务方法变得如此复杂。你应该可以这样做。

代码语言:javascript
复制
@Transactional
public void insertUser(User user) {
  entityManager.persist( user );
}

如果有需要访问原生Hibernate Session的地方,您可以简单地展开并直接使用Session,如下所示:

代码语言:javascript
复制
@Transactional
public void doSomethingFancyWithASession() {
  Session session = entityManager.unwrap( Session.class );
  // use session as needed
}

这里的概念是,Spring通过使用@PersistenceContext注释为您提供了一个已经可以正常工作的EntityManager实例。该实例将安全地被执行spring bean的当前线程使用。

其次,通过使用@Transactional,这会使Spring的事务管理根据您的环境配置自动确保EntityManager绑定到事务,无论是RESOURCE_LOCAL事务还是JTA事务。

由于对#getCurrentSession()的调用,您遇到了问题。

发生的事情是Spring创建了EntityManager,然后在您的方法中调用#getCurrentSession()时,您要求Hibernate创建第二个会话,该会话不绑定到由@Transactional注释启动的事务。简而言之,它本质上类似于以下内容:

代码语言:javascript
复制
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

因此,遵循我上面提到的范例,你应该不会再遇到这个问题。如果您适当地允许Spring为您注入EntityManager实例,那么您应该永远不需要在Spring环境中调用#getCurrentSession()#openSession()

票数 16
EN

Stack Overflow用户

发布于 2019-02-16 16:46:32

当我将我的spring boot应用程序部署到WebLogic服务器上时,我也犯了同样的错误。(如果我直接通过Eclipse (或部署到Tomcat)运行它,它也能正常工作)。

我通过将@EnableTransactionManagement添加到UserService解决了这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50650041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档