`

Hibernate的evict方法错误总结

阅读更多

摘自百度知道:http://zhidao.baidu.com/question/63663640.html

问:
先创建一个Student,然后调用session.save方法,然后再调用evict方法把Student对象清除出缓存,再提交事务,
可是会报错:Exception in thread "main" org.hibernate.AssertionFailure: possible nonthreadsafe access to session
但是如果我用的不是evict方法,而是clear方法用来清除缓存的话,程序没有错。

答:
session.evict(obj),会把指定的缓冲对象进行清除
session.clear(),把缓冲区内的全部对象清除,但不包括操作中的对象

所以,hibernate执行的顺序如下,

(1)生成一个事务的对象,并标记当前的Session处于事务状态(注:此时并未启动数据库级事务)。
(2)应用使用s.save保存对象,这个时候Session将这个对象放入entityEntries,用来标记对象已经
和当前的会话建立了关联,由于应用对对象做了保存的操作,Session还要在insertions中登记应用
的这个插入行为(行为包括:对象引用、对象id、Session、持久化处理类)。

(3)s.evict将对象从s会话中拆离,这时s会从entityEntries中将这个对象移出。
(4)事务提交,需要将所有缓存flush入数据库,Session启动一个事务,并按照insert,update,……,
delete的顺序提交所有之前登记的操作(注意:所有insert执行完毕后才会执行update,这里的特殊
处理也可能会将你的程序搞得一团糟,如需要控制操作的执行顺序,要善于使用flush),现在对象不
在entityEntries中,但在执行insert的行为时只需要访问insertions就足够了,所以此时不会有任何
的异常。异常出现在插入后通知Session该对象已经插入完毕这个步骤上,这个步骤中需要将entityEntries
中对象的existsInDatabase标志置为true,由于对象并不存在于entityEntries中,此时Hibernate就
认为insertions和entityEntries可能因为线程安全的问题产生了不同步(也不知道Hibernate的开发者
是否考虑到例子中的处理方式,如果没有的话,这也许算是一个bug吧),于是一个net.sf.hibernate.AssertionFailure
就被抛出,程序终止


一般错误的认为s.save会立即的执行,而将对象过早的与Session拆离,造成了Session的insertions
和entityEntries中内容的不同步。所以我们在做此类操作时一定要清楚Hibernate什么时候会将数据
flush入数据库,在未flush之前不要将已进行操作的对象从Session上拆离。

解决办法是在save之后,添加session.flush。

分享到:
评论

相关推荐

    Hibernate中get和load方法的区别以及close(),clear()、evict()等的区别

    在Hibernate框架中,Session是与数据库交互的主要接口,它提供了多种方法来操作对象的状态和数据。本文主要讨论了`get`、`load`方法以及`flush`、`clear`、`evict`等方法的区别。 首先,让我们关注`get`和`load`的...

    hibernate中evict()和clear()的区别.docx

    总的来说,`evict()`和`clear()`都是用于管理Hibernate Session缓存的方法,但它们处理的对象范围和时机不同。理解这两个方法的差异,可以帮助我们更有效地控制对象的状态,避免潜在的运行时异常,并提高应用程序的...

    关于flush和evict

    在持久层框架Hibernate中,`flush()`和`evict()`方法是开发者在处理数据时经常会遇到的两个重要概念。它们对于理解Hibernate的工作机制及其缓存管理至关重要。本文将通过一系列具体的示例来探讨这两个方法的作用与...

    SSH(struts+spring+hibernate)面试题总结

    `Session.save()`, `Session.load()`, `Session.get()`等方法会将对象置于持久化状态。 - **游离状态(Detached)**:对象不再在Session缓存中,但数据库可能仍有记录。关闭Session或调用`Session.evict()`会使得对象...

    西安领航核心项目Hibernate部分重点、难点总结

    西安领航核心项目的Hibernate部分,涉及了许多重要的概念和操作,其中包含了对象状态管理、方法区别、执行顺序以及关联关系处理等关键知识点。以下是对给定文件中提到的关键知识点的详细解读: ### 持久化对象的三...

    Hibernate总结

    【Hibernate总结】 Hibernate是一款强大的Java持久化框架,用于简化数据库操作。它提供了对象关系映射(ORM)功能,使得开发者可以使用面向对象的方式来处理数据库事务。以下是对Hibernate中一些核心概念和操作的...

    Hibernate的事务处理机制和flush方法的用法.docx

    1. 在事务中,如果先调用了`evict`方法移除对象,然后尝试提交事务,由于对象已经从缓存中移除,Hibernate无法找到对应的数据库记录进行更新,从而抛出异常。 2. 当执行了多个对象的插入或更新操作,没有在每个操作...

    hibernate的flush机制

    当开发人员调用Session的`save()`, `update()`, `delete()`等方法时,Hibernate并不会立即执行SQL语句,而是将这些操作记录在其内部的一系列映射和集合中,如`entityEntries`, `insertions`, `deletions`, `updates`...

    Hibernate对象状态以及各种保存方法的区别

    - 当事务结束或 `Session` 调用了 `close()`、`clear()` 或 `evict()` 方法,持久对象会变成脱管对象。 3. **脱管对象(Detached Objects)** - 脱管对象是之前是持久对象,但在 `Session` 关闭后失去与它的关联...

    Hibernate工作原理及为什么要用

    Java 对象可以通过 Session 的 close() 方法或 evict() 方法,从缓存中删除一个对象时进入游离状态。 四、为什么要用 Hibernate? 使用 Hibernate 可以大大减少操作数据库的工作量。Hibernate 可以简化载入类的...

    深入理解Hibernate缓存

    - **显式清除**:可以显式调用`evict()`方法从缓存中移除某个实体或所有实体。 ### 结语 本文详细介绍了Hibernate中的一级缓存和二级缓存,并探讨了如何根据具体应用场景来配置不同的缓存策略。理解并合理利用...

    Hibernate 使用缓存时,数据同步问题

    4. **清除缓存**:在必要的时候,可以显式地调用`Session.clear()`方法清除一级缓存,或者使用`SessionFactory.evict()`方法清除二级缓存中的特定实体,以确保下一次操作时能获取到最新的数据。 5. **配置缓存模式*...

    hibernate BASEDAO

    8. **缓存支持(Caching)**:如果项目中启用了Hibernate的二级缓存,BaseDAO可能会包含与缓存相关的操作,如`evict(T entity)`来清除特定对象的缓存,或`clearCache()`清空整个缓存。 `Hibernate通用的baseDao - ...

    《深入浅出Hibernate》读书笔记

    一级缓存是Session级别,即每个Session有自己的缓存,通常由Hibernate自动管理,可以使用Session.evict()方法手动清除对象。二级缓存是SessionFactory级别,可跨Session共享,适用于多个用户或请求间的共享数据。...

    hibernate缓存

    5. **手动清除缓存**:必要时可通过`evict`方法清除特定实体的缓存,或者使用`clear`方法清除整个一级缓存。 #### 七、总结 通过对Hibernate缓存机制的理解和合理配置,可以显著提升应用程序的性能表现,降低...

    hibernate一级缓存

    2. **及时清理无用对象**:在业务逻辑中,可以适时调用`Session.evict()`方法,手动将不再需要的对象从缓存中移除。 3. **合理划分Session边界**:尽量减少长时间开启的Session,避免大量对象堆积在一级缓存中。 4...

    hibernate-3.2.rar

    13. **实体生命周期**:Hibernate 3.2定义了对象的生命周期,包括`Transient`, `Persistent`, `Detached`三种状态,并提供了`merge()`, `evict()`, `refresh()`等方法来控制对象的状态转换。 14. **代理对象**:在...

    hibernate 调优

    可以通过 Session.evict 或 Session.clear 方法手动清理缓存,这对于处理大量数据非常有用。 3. **应用缓存**:在整个 SessionFactory 生命周期内有效。使用前需评估数据是否会频繁更新、是否由第三方修改等因素。 ...

    hibernate的一级缓存和二级缓存

    然而,一级缓存中对象不会自动过期,除非手动通过Session的evict()方法清除特定对象,或者通过clear()方法清空整个缓存。 二级缓存则是在SessionFactory级别,跨越多个Session,甚至整个应用进程或集群。这意味着,...

Global site tag (gtag.js) - Google Analytics