Hibernate(十九): 异常"Session was already closed"
中,针对"Session was already closed"异常,我们发现最终调用了transactionContext.managedClose方法来关掉了session, 那么这个过程具体是什么样的? 这篇中将加以梳理
.
在JDBCTransaction类(Transaction接口的一个实现类)具体决定是否要关session的方法closeIfRequired
里, 有这么一个复合条件决断: if(callback &&
transactionContext.shouldAutoClose() &&
!transactionContext.isClosed() ). 这三个条件分别代表什么?
首先看这个
callback, 在
JDBCTransaction
类的begin方法里(session.beginTransaction()方法最终要调用这个begin),看到这样的赋值: callback
= jdbcContext.registerCallbackIfNecessary();
registerCallbackIfNecessary方法的实现有些奇怪, 如下所示:
public boolean registerCallbackIfNecessary() {
if ( isTransactionCallbackRegistered ) {
return false;
}
else {
isTransactionCallbackRegistered = true;
return true;
}
}
如果isTransactionCallbackRegistered
为true就返回false, 如果是false,把它set为true后返回true. 有些奇怪. 不过, 这里不过多讨论了, debug时发现这里返回的是true.
再看第二个
transactionContext.shouldAutoClose().这里的主角transactionContext
是TransactionFactory.Context接口, 它什么时候set到
JDBCTransaction
类的,
JDBCTransaction类的构造方法里,即JDBCTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext). 为了追
transactionContext是从哪来的,看
这个构造方法又是何时调用. JDBCTransactionFactory里的createTransaction方法, 这个方法又在JDBCContext类的createTransaction( this, owner )
里,这里的的owner就是我们一直追的transactionContext,
那么这个owner是什么它又来自何方呢? 来自JDBCContext(Context owner, Connection
connection, Interceptor interceptor)构造方法.如下是整个跟踪路径:
最终在SessionImpl类的构造方法里对jdbcContext的赋值语句看到了,owner就是this,即SessionImpl对象.
this.jdbcContext = new JDBCContext( this, connection, interceptor );
也就是说SessionImpl类实现了TransactionFactory.Context接口(以实现JDBCContext.Context子接口方式间接来的).
看到这里, 根源找到了, 也就是说transactionContext.shouldAutoClose()是要调用
SessionImpl类的shouldAutoClose方法,
shouldAutoClose方法
又
有调用isAutoCloseSessionEnabled() &&
!isClosed(),最终看到是看isAutoCloseSessionEnabled方法里的autoCloseSessionEnabled属
性. 那这么个属性又是何时set的,源头在哪?
可从下图的方法调用栈,看到了源头: ThreadLocalSessionContext类里的isAutoCloseEnabled方法,
通过"return true;"写死的!
这
里有一个不舒服的地方: SessionImpl实现了JDBCContext.Context接口,
虽说接口JDBCContext.Context继承自TransactionFactory.Context,但让SessionImpl这么早地就跟
具体JDBCXXXX绑定还是有些别扭, 有些畸形.
对第二个条件的跟踪很是艰辛, 下面看第三个条件: !transactionContext.isClosed(), 应该说有了上面很是艰辛的分析后, 这里很自然地得知这里的第三个条件是调用了
SessionImpl
实现类的相应方法. (这里有个注意点:
isClosed方法恰好也是SessionImplementor接口定义的,这样在SessionImpl(父类)里一石二鸟地对两个接口定义的方法
做了实现,
再往一想,是不是可以抽出一个接口closable,让SessionImplementor和TransactionFactory.Context两
个接口做下继承?)
分享到:
相关推荐
《深入理解Hibernate Session:从配置到实践》 Hibernate,作为Java领域中一款广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作。在Hibernate中,Session是连接应用程序和数据库的重要桥梁,它负责对象...
通过begin()开启事务,Hibernate会自动创建Session,然后在commit()或rollback()时关闭Session。这种方法简化了代码,但可能导致Session生命周期过长,增加内存压力。 总的来说,理解和熟练运用Hibernate的缓存机制...
【标题】"Hibernate教程20_关系映射案例三"主要涵盖了在Hibernate框架中如何进行对象关系映射(ORM)的实践,特别是针对复杂关系的处理。在这个教程中,我们可能会学习到以下关键知识点: 1. **关系映射**:...
尽管默认情况下文件名为`hibernate.cfg.xml`,但开发者可以根据需要自定义该文件的名称或存储位置。如果选择自定义配置文件的位置或名称,则需要通过`HibernateSessionFactory`类中的`CONFIG_FILE_LOCATION`属性来...
Hibernate默认使用的是可重复读,避免了脏读和不可重复读的问题,但可能会出现幻读。根据具体应用场景,开发者可以调整隔离级别。 **4. 乐观锁和悲观锁** - **乐观锁**:假设并发冲突较少,只在更新时检查版本号等...
### Tomcat下配置Hibernate知识点详解 #### 一、前言 在Java Web开发中,Tomcat作为一款轻量级的应用服务器被广泛使用。而在实际项目中,为了更好地管理数据库连接和进行对象关系映射(ORM),Hibernate框架因其...
3. Configuration:读取配置文件(默认为hibernate.cfg.xml)并生成SessionFactory,SessionFactory是线程安全的,负责创建Session实例。 4. Session:类似于JDBC中的Connection,是轻量级对象,不适用于并发环境,...
"第一个手写Hibernate"项目旨在帮助开发者深入理解Hibernate的工作原理,通过手动编写相关代码,以实践的方式来学习和掌握Hibernate的核心概念。 **一、Hibernate简介** Hibernate是一个开源的ORM框架,它允许...
它通过设置连接的自动提交属性为`false`来开启事务,并在提交或回滚时恢复到默认状态。 ```java Session session = sf.openSession(); Transaction tx = session.beginTransaction(); // 执行业务逻辑 ...
- 自动提交事务:默认情况下,Hibernate会在每个操作后自动提交事务。 - **映射机制**: - 类到表的映射:使用注解或XML配置文件定义类与数据库表之间的映射关系。 - 属性到列的映射:指定类的属性如何映射到...
但在某些情况下,可能会分开使用 `hibernate.properties` 和 `hibernate.cfg.xml` 两个文件: - `hibernate.properties`: 主要用于配置数据连接、二级缓存、连接池等信息。 - `hibernate.cfg.xml`: 主要用于配置...
- **懒加载**:默认情况下,关联的对象不会立即加载,只有在需要时才会加载,以提高性能。 - **级联操作**:通过`@OneToMany`、`@ManyToOne`等注解可以配置级联操作,如同时保存、删除关联的对象。 通过本示例,...
Struts和Hibernate是Java开发中两个非常重要的框架,它们分别专注于Web层和持久化层的管理。Struts作为MVC(Model-View-Controller)框架,主要负责处理HTTP请求,控制业务逻辑,以及与视图的交互。而Hibernate则是...
3. Transaction:事务管理是数据库操作的关键,Hibernate提供了集成的事务处理,通过Session的beginTransaction和commit/rollback方法来控制事务边界。 三、对象持久化 Hibernate通过映射文件(.hbm.xml)或注解将...
Hibernate Core API是Java开发人员在使用Hibernate ORM框架时最常打交道的部分。它是Hibernate框架的核心组件,提供了对数据库操作的基本抽象和实现。版本3.3.1是该API的一个稳定版本,支持多种数据库交互功能,包括...
Hibernate 是一个开源的对象关系映射(ORM)框架,它允许Java开发者将数据库操作转化为对象间的操作,极大地简化了数据存取的过程。Hibernate3 API 手册是开发者在使用Hibernate进行数据库交互时的重要参考资料,它...
8. **第二级缓存**:除了默认的一级缓存(Session级别的缓存),Hibernate还支持二级缓存,用于存储多个Session共享的数据,提高性能。可以通过配置插件如EhCache实现。 9. **Transaction管理**:Hibernate提供了...
Hibernate使用Session的beginTransaction()、commit()和rollback()方法处理事务。事务的隔离级别和传播行为可以通过配置文件设置。 7. **缓存机制**: Hibernate内置了一级缓存(Session级别的)和二级缓存...
- **CriteriaQuery**: 提供了一个灵活的方式来构建查询条件。 - **HQL (Hibernate Query Language)**: 类似SQL,但面向对象的方式进行查询。 ##### 7. 数据关联 - **一对一关联**: - 单向一对一: 一方持有另...
第一级缓存是默认开启的,每个Session都有自己的缓存。第二级缓存是可选的,是跨Session共享的,可以使用第三方缓存提供者如Ehcache或Infinispan。 7. Hibernate支持哪些查询语言? Hibernate支持两种查询语言:...