evict方法是从当前缓存中移除某个持久化实例.
flush作用是将数据库与缓存中的数据同步.
当flush后,这个持久化实例没有从缓存中移除,除非调用evict或者session.close();
在一个session线程中,如果存在多个insert,update,delete操作。Habernate会先把insert批量操作,然后是update,然后是delete。而不是按照我们代码的编写顺序进行执行。在某些情况下,这个特点会引起一些错误。
public void testFulsh_Evict1(){
Session session = HibernateUtils.getSession();
try {
session.beginTransaction();
Group group = new Group();
group.setName("猛牛集团");
session.save(group);
group.setName("蒙牛集团");
//update时不会发出sql语句,commit时才能发出sql
session.update(group);
//这里如果不用flush同步数据的,会接着执行下面的代码
//最后在commit之前才会走这一部,不符合我们的逻辑
session.flush();
User user =new User();
user.setName("牛根生");
user.setGroup(group);
session.save(user);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
加入flush后,控制台输出的sql语句符合我们代码的流程:
Hibernate: insert into t_group (g_name) values (?)
Hibernate: update t_group set g_name=? where g_id=?
Hibernate: insert into t_user (u_name, u_group) values (?, ?)
使用uuid策略做主键时,例如insert一条记录,save完了,可以手动flush后evict。
使用native策略的主键时,save完后,可以直接手动evict,因为native主键策略下save自动完成了flush。
小常识:
所有的增删改操作,只要操作的是persistent状态的对象,数据库中有对应记录的,就不会在save、update、delete方法后马上执行sql语句,而是在commit时才执行所有的sql。
transistence对象在save的时候,主键生成策略只要不是依赖数据库生成的,在save的时候也不会发出sql语句,
uuid策略和assigned(手动分配)不是依赖数据库生成的,native是依赖数据库的。
相关链接:
http://apps.hi.baidu.com/share/detail/17203428
分享到:
相关推荐
例如,在第四个测试方法中,执行`evict(person2)`后,再执行`flush()`时,由于Session缓存中没有待插入的数据,因此不会有数据被插入到数据库。 #### 四、总结 通过上述分析可以看出,`flush()`和`evict()`在...
本文主要讨论了`get`、`load`方法以及`flush`、`clear`、`evict`等方法的区别。 首先,让我们关注`get`和`load`的区别: 1. **返回结果对比**: - `load`方法如果找不到对应的记录,会抛出`org.hibernate....
`evict()`和`clear()`方法都是用于管理Session缓存中的对象,但它们的作用和使用场景有所不同。理解这些概念对于优化Hibernate应用程序和避免潜在问题至关重要。 首先,`session.evict(obj)`方法是用来从缓存中移除...
然而,由于`evict()`操作将`cat`从`entityEntries`中移除,但在事务提交时(即Flush操作时),Hibernate无法找到`cat`对象的引用,从而导致`AssertionFailure`异常,提示可能的非线程安全访问或不正确的Session使用...
1. 在事务中,如果先调用了`evict`方法移除对象,然后尝试提交事务,由于对象已经从缓存中移除,Hibernate无法找到对应的数据库记录进行更新,从而抛出异常。 2. 当执行了多个对象的插入或更新操作,没有在每个操作...
根据提供的文件信息,我们可以深入探讨Hibernate中的几个关键概念与操作,包括`Session.flush()`方法的使用、不同主键生成策略下的保存操作等。 ### Hibernate Session.flush() 方法详解 #### 一、基本概念 在...
- 显式调用`session.flush()`方法。 总结来说,Hibernate的持久化机制和一级缓存是其高效处理数据库操作的关键。理解并熟练掌握这些概念,可以帮助开发者编写更高效、更易于维护的Java应用。在实际项目中,合理利用...
在每次更新后调用`session.flush()`强制Hibernate执行当前的数据库操作,然后使用`session.evict(entity)`将实体从缓存中移除。这样做可以确保每个更新操作仅执行一次,并且避免了持久化上下文中的内存浪费。 ```...
1. **使用`flush()`和`evict()`方法**:在修改实体后,主动调用`session.flush()`方法,使Hibernate将缓存中的变更同步到数据库,然后调用`session.evict(entity)`方法,从缓存中移除实体,这样下一次操作不会受到...
通过合理利用`flush()`、`evict()`以及直接使用JDBC执行SQL,可以有效地处理大数据量的更新和删除操作,降低内存占用并减少对数据库的访问次数。在实际开发中,应根据具体需求和数据规模选择合适的方法,确保系统...
2. **及时清理无用对象**:在业务逻辑中,可以适时调用`Session.evict()`方法,手动将不再需要的对象从缓存中移除。 3. **合理划分Session边界**:尽量减少长时间开启的Session,避免大量对象堆积在一级缓存中。 4...
session.evict(customer); // 从一级缓存中移除customer对象 session.clear(); // 清空一级缓存 boolean contains = session.contains(customer); // 检查一级缓存是否包含customer session.flush(); // 刷新缓存,...
1. **显式控制更新**:如果你不想让Hibernate自动更新实体,可以在修改完对象后,调用`Session.evict(entity)`方法将实体从Session缓存中移除,这样就不会触发自动更新。或者,如果不希望整个实体被更新,可以只更新...
可以通过关闭 Session 或使用 `evict()` 方法将持久化对象移出缓存。 3. Session 的操作方法 - **save()**:将对象加入缓存,变为持久化对象,并分配唯一 OID。插入操作会在缓存清理时执行。 - **update()**:将...
**持久化状态(Persistent) -> 游离状态(Detached)**:关闭Session,或者调用`evict()`, `clear()`方法,使得对象离开Session的管理范围,进入游离状态。即使对象原本是持久化的,也会因为失去了Session的管理而变为...
此时,对象与数据库中的一个记录对应,并且在Session的生命周期内,对象的任何改变都会在Session关闭时通过flush()方法同步到数据库。使用Session的persist()方法可以将瞬时态对象转变为持久态。 3. **游离态...
如果一个持久态对象的Session被关闭或者调用了`evict()`方法,那么对象将变为游离态。即使数据库中仍有记录,内存中的对象与Session缓存不再关联。若对游离态对象进行修改,需要手动使用`merge()`或`saveOrUpdate()...
使用`session.flush()`可强制执行当前点的SQL语句,避免顺序问题。 ### Close、Clear及Evict方法的区别 - **Close**:关闭Session,所有Session内的对象变为离线状态。 - **Clear**:清除Session缓存,使所有对象...
- **持久态 ↔️ 游离态**:可通过`session.evict()`、`session.close()`或`session.clear()`等方法使对象进入游离态。 - **游离态 → 持久态**:使用`session.update()`或`session.saveOrUpdate`方法将游离态对象...
7. **避免不必要的修改追踪**:如果你知道某个对象不应该被持久化,可以在获取实例后将其转为游离状态,例如通过`Session.evict(entity)`。游离对象的修改不会被Hibernate跟踪。 8. **Transaction的隔离级别**:...