在SpringFramework中使用Hibernate openSession()和getCurrentSession()

时间:2017-02-28 10:39:53

标签: hibernate spring-boot spring-data spring-orm

请参阅以下示例。

@Repository
public class ContactDAOImpl implements ContactDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public List<Contact> findAll() {
        Session session = sessionFactory.openSession();
        return session.createQuery("from Contact").list();
    }
}

在调用session.openSession()之前,spring已经通过OpenEntityManagerInViewInterceptor为该线程创建了一个会话。

即使我手动关闭会话(考虑answer),如下所示

    @Override
    public List<Contact> findAll() {
        Session session;
        try{
            session = sessionFactory.openSession();
            return session.createQuery("from Contact").list();
        }finally{
            if(session!=null){
                session.close(); //logs says it is closed, but actually it gets closed via OpenEntityManagerInViewInterceptor, not by this call.
            }
        }
    }

仍然Spring持有会话并通过OpenEntityManagerInViewInterceptor关闭它。

如果有人向我解释在Spring容器中使用Hibernate会话,那就非常感激。

何时使用openSession()getCurrentSession()以及何时不使用它们?

更新:

上述两个例子都运行正常。但为什么呢?

如果我将getCurrentSession()与配置spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext一起使用,它也可以正常工作。

UPDATE2:

当我使用session.openSession()时,这是我得到的日志输出。您将在日志末尾看到会话(SessionImpl)即将关闭。

2017-03-01 10:28:31.106 DEBUG 6008 --- [io-8080-exec-10] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2017-03-01 10:28:31.106 TRACE 6008 --- [io-8080-exec-10] .i.SessionFactoryImpl$SessionBuilderImpl : Opening Hibernate Session.  tenant=null, owner=org.hibernate.jpa.internal.EntityManagerImpl@445e7f4a
2017-03-01 10:28:31.107 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : Opened session at timestamp: 14883443111
2017-03-01 10:28:31.108 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : Setting flush mode to: AUTO
2017-03-01 10:28:31.109 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : Setting cache mode to: NORMAL
2017-03-01 10:28:31.110 DEBUG 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@445e7f4a] for JPA transaction
2017-03-01 10:28:31.110 DEBUG 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [com.sura2k.hbm.business.ContactServiceImpl.findAll]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
2017-03-01 10:28:31.111 DEBUG 6008 --- [io-8080-exec-10] o.s.jdbc.datasource.DataSourceUtils      : Setting JDBC Connection [ProxyConnection[PooledConnection[conn9: url=jdbc:h2:mem:contactsdb user=SA]]] read-only
2017-03-01 10:28:31.112 DEBUG 6008 --- [io-8080-exec-10] o.h.e.t.internal.TransactionImpl         : begin
2017-03-01 10:28:31.112 TRACE 6008 --- [io-8080-exec-10] j.i.AbstractLogicalConnectionImplementor : Preparing to begin transaction via JDBC Connection.setAutoCommit(false)
2017-03-01 10:28:31.112 TRACE 6008 --- [io-8080-exec-10] j.i.AbstractLogicalConnectionImplementor : Transaction begun via JDBC Connection.setAutoCommit(false)
2017-03-01 10:28:31.112 TRACE 6008 --- [io-8080-exec-10] cResourceLocalTransactionCoordinatorImpl : ResourceLocalTransactionCoordinatorImpl#afterBeginCallback
2017-03-01 10:28:31.113 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : Setting flush mode to: MANUAL
2017-03-01 10:28:31.113 DEBUG 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@34b8834a]
2017-03-01 10:28:31.114 TRACE 6008 --- [io-8080-exec-10] .i.SessionFactoryImpl$SessionBuilderImpl : Opening Hibernate Session.  tenant=null, owner=null
2017-03-01 10:28:31.116 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : Opened session at timestamp: 14883443111
2017-03-01 10:28:31.116 TRACE 6008 --- [io-8080-exec-10] o.h.engine.query.spi.QueryPlanCache      : Located HQL query plan in cache (from ContactEntity)
2017-03-01 10:28:31.117 TRACE 6008 --- [io-8080-exec-10] o.h.engine.query.spi.QueryPlanCache      : Located HQL query plan in cache (from ContactEntity)
2017-03-01 10:28:31.117 TRACE 6008 --- [io-8080-exec-10] o.h.engine.query.spi.HQLQueryPlan        : Find: from ContactEntity
2017-03-01 10:28:31.117 TRACE 6008 --- [io-8080-exec-10] o.hibernate.engine.spi.QueryParameters   : Named parameters: {}
2017-03-01 10:28:31.118 DEBUG 6008 --- [io-8080-exec-10] org.hibernate.SQL                        : select contactent0_.contactid as contacti1_0_, contactent0_.email as email2_0_, contactent0_.name as name3_0_ from contact contactent0_
2017-03-01 10:28:31.119 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.ResourceRegistryStandardImpl   : Registering statement [prep10: select contactent0_.contactid as contacti1_0_, contactent0_.email as email2_0_, contactent0_.name as name3_0_ from contact contactent0_]
2017-03-01 10:28:31.120 TRACE 6008 --- [io-8080-exec-10] o.h.e.jdbc.internal.JdbcCoordinatorImpl  : Registering last query statement [prep10: select contactent0_.contactid as contacti1_0_, contactent0_.email as email2_0_, contactent0_.name as name3_0_ from contact contactent0_]
2017-03-01 10:28:31.121 TRACE 6008 --- [io-8080-exec-10] org.hibernate.loader.Loader              : Bound [1] parameters total
2017-03-01 10:28:31.121 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.ResourceRegistryStandardImpl   : Registering result set [rs23: org.h2.result.LocalResult@4e4e3165 columns: 3 rows: 0 pos: -1]
2017-03-01 10:28:31.121 TRACE 6008 --- [io-8080-exec-10] org.hibernate.loader.Loader              : Processing result set
2017-03-01 10:28:31.121 TRACE 6008 --- [io-8080-exec-10] org.hibernate.loader.Loader              : Done processing result set (0 rows)
2017-03-01 10:28:31.121 TRACE 6008 --- [io-8080-exec-10] org.hibernate.loader.Loader              : Total objects hydrated: 0
2017-03-01 10:28:31.122 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.ResourceRegistryStandardImpl   : Releasing statement [prep10: select contactent0_.contactid as contacti1_0_, contactent0_.email as email2_0_, contactent0_.name as name3_0_ from contact contactent0_]
2017-03-01 10:28:31.122 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.ResourceRegistryStandardImpl   : Closing result set [rs23: org.h2.result.LocalResult@4e4e3165 columns: 3 rows: 0 pos: 0]
2017-03-01 10:28:31.122 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.ResourceRegistryStandardImpl   : Closing prepared statement [prep10: select contactent0_.contactid as contacti1_0_, contactent0_.email as email2_0_, contactent0_.name as name3_0_ from contact contactent0_]
2017-03-01 10:28:31.123 TRACE 6008 --- [io-8080-exec-10] o.h.e.jdbc.internal.JdbcCoordinatorImpl  : Starting after statement execution processing [ON_CLOSE]
2017-03-01 10:28:31.123 TRACE 6008 --- [io-8080-exec-10] o.h.e.i.StatefulPersistenceContext       : Initializing non-lazy collections
2017-03-01 10:28:31.123 TRACE 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Triggering beforeCommit synchronization
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Triggering beforeCompletion synchronization
2017-03-01 10:28:31.124 DEBUG 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit
2017-03-01 10:28:31.124 DEBUG 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@445e7f4a]
2017-03-01 10:28:31.124 DEBUG 6008 --- [io-8080-exec-10] o.h.e.t.internal.TransactionImpl         : committing
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] cResourceLocalTransactionCoordinatorImpl : ResourceLocalTransactionCoordinatorImpl#beforeCompletionCallback
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : SessionImpl#beforeTransactionCompletion()
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] .t.i.SynchronizationRegistryStandardImpl : SynchronizationRegistryStandardImpl.notifySynchronizationsBeforeTransactionCompletion
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] j.i.AbstractLogicalConnectionImplementor : Preparing to commit transaction via JDBC Connection.commit()
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] j.i.AbstractLogicalConnectionImplementor : Transaction committed via JDBC Connection.commit()
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] j.i.AbstractLogicalConnectionImplementor : LogicalConnection#afterTransaction
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.ResourceRegistryStandardImpl   : Releasing JDBC resources
2017-03-01 10:28:31.124 TRACE 6008 --- [io-8080-exec-10] j.i.AbstractLogicalConnectionImplementor : re-enabling auto-commit on JDBC Connection after completion of JDBC-based transaction
2017-03-01 10:28:31.126 TRACE 6008 --- [io-8080-exec-10] cResourceLocalTransactionCoordinatorImpl : ResourceLocalTransactionCoordinatorImpl#afterCompletionCallback(true)
2017-03-01 10:28:31.126 TRACE 6008 --- [io-8080-exec-10] .t.i.SynchronizationRegistryStandardImpl : SynchronizationRegistryStandardImpl.notifySynchronizationsAfterTransactionCompletion(3)
2017-03-01 10:28:31.126 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : SessionImpl#afterTransactionCompletion(successful=true, delayed=false)
2017-03-01 10:28:31.126 TRACE 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Triggering afterCommit synchronization
2017-03-01 10:28:31.126 TRACE 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Triggering afterCompletion synchronization
2017-03-01 10:28:31.126 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : Setting flush mode to: AUTO
2017-03-01 10:28:31.127 DEBUG 6008 --- [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Not closing pre-bound JPA EntityManager after transaction
2017-03-01 10:28:31.132 DEBUG 6008 --- [io-8080-exec-10] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2017-03-01 10:28:31.132 DEBUG 6008 --- [io-8080-exec-10] o.s.orm.jpa.EntityManagerFactoryUtils    : Closing JPA EntityManager
2017-03-01 10:28:31.132 TRACE 6008 --- [io-8080-exec-10] org.hibernate.internal.SessionImpl       : Closing session
2017-03-01 10:28:31.132 TRACE 6008 --- [io-8080-exec-10] o.h.e.jdbc.internal.JdbcCoordinatorImpl  : Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@69c176d4]
2017-03-01 10:28:31.133 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.ResourceRegistryStandardImpl   : Releasing JDBC resources
2017-03-01 10:28:31.133 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.LogicalConnectionManagedImpl   : Closing logical connection
2017-03-01 10:28:31.133 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.ResourceRegistryStandardImpl   : Releasing JDBC resources
2017-03-01 10:28:31.133 TRACE 6008 --- [io-8080-exec-10] o.h.r.j.i.LogicalConnectionManagedImpl   : Logical connection closed

我也尝试使用VisualVM Profiler监控它。在向http://localhost:8080/contact发出5个请求后,我只能看到SessionImpl的一个实例。 enter image description here

此外,我在此处上传了一个更简单的版本https://bitbucket.org/sura2k/tests,我曾经测试过。

0 个答案:

没有答案