请参阅以下示例。
@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
的一个实例。
此外,我在此处上传了一个更简单的版本https://bitbucket.org/sura2k/tests,我曾经测试过。