Spring boot hibernate no transaction is in progress

后端 未结 2 1451
暖寄归人
暖寄归人 2021-01-13 01:07

I\'m using spring boot and it perfectly makes me entity manager. And I decided to test getting session factory from the entity manager and to use it for an example. But I ge

相关标签:
2条回答
  • 2021-01-13 01:42

    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:

    @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. That instance will safely be usable by the current thread your spring bean is being executed within.

    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.

    You're running into your problem because of the call to #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. 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.

    0 讨论(0)
  • 2021-01-13 01:54

    I have same your error, when I deploy my spring boot app to WebLogic Server. (Even It works fine if I run it directly via Eclipse (Or deploy to Tomcat) ).

    I solved the problem by adding @EnableTransactionManagement to UserService.

    0 讨论(0)
提交回复
热议问题