Hibernate 持久化上下文总结

Session和EntityManager代表的是持久化上下文,持久化对象的状态与持久化上下文和底层数据库都有关系

四种状态:

1.new和transient:new出来的对象,没有数据库标识符,也没有关联上持久化上下文

2.managed和persistent:同时关联了持久化上下文和数据库标识符

3.detached:关联了数据库标识符,但是不再关联持久化上下文(可能持久化上下文已关闭或者实体已被evicted)

4.remove:同时关联了持久化上下文和数据库标识符,但是已经被计划从数据库删除

实体对象状态的转变

1.使之持久化

session.save和entityManager.persist

hibernate session也支持persist

如果是generated标识符,save和persist调用后会生成,如果不是auto generated的,需要在调用之前设置标识符。

save和persist的两个区别:1.persist不保证方法调用完后肯定返回数据库标识符,是在flush后才生成数据库标识符,而save保证返回标识符。2.因为1所以persist保证在事务边界外不会调用insert,而save不管是否在事务内部都会执行insert(当需要执行insert才能得到标识符的时候,例如identify(sql server和mysql支持的自增字段))

2.删除实体

session.delete和entityManager.remove

把一个持久实例变成瞬时实例,两个方法的区别:hibernate delete可以删除处于detached状态和managed状态的对象,但是entitymanager remove只能删除managed状态的对象

3.加载实体不加载数据

session.byId.getreference(4.0之前是load)和entityManager.getReference

允许延迟加载,通常是获得的一个运行时代理,如果数据库不存在此数据,当真正调用其方法时,会抛出异常

4.加载实体并初始化数据

session.byId.load(4.0之前是get)和entityManager.find

会查询数据库,如果没有匹配的记录会返回null,如果不确定数据是否存在,应该使用get方法,get方法可以带lock访问,编程select……for update方式

5.加载实体通过自然键

hibernate4.2新特性,和使用标识符一样的可以加载引用或者加载数据

6.刷新实体状态

session.refresh

同步数据库状态的变化到已经加载的实体

7.修改管理持久化状态

session.flush

已经处于managed和persistent的对象,只需调用flush,就能把状态同步到数据库

可以设置session flush的时间,默认会在事务提交和执行一些查询之前,自动flush

8.管理托管状态的实体

四种方式使实体编程托管态

1.close session

2.clear session

3.evicted 一个实体

4.序列化会把反序列化形式的变成托管态(原实体还是处于持久态)

Reattaching detached data

1.session.update和session.saveorupdate

可以吧对象重新编程持久态,但是sql更新不是马上执行,而是在flush的时候。并且如果不设置实体映射为select-before-update,不管是否更新,都会执行update语句

如果新的session已经load了一个相同标识符的持久态对象,则update会报异常

当实体是托管态时,update和saveorupdate是一样的。saveorupdate使用unsaved value来判断是更新还是新增,所以如果主键策略是assign的话是不行的

2.session.merge和entityManager.merge

查询出一个持久态对象,将托管态对象的数据copy到持久态对象上进行更新

3.session.lock

当对象没有改变的时候,lock方法也可以把对象重新关联到session

9.检查持久化状态

1.contains , isIinitialization和javax.persistence.PersistenceUnitUtil jpaUtil.isloaded

检查是否在持久态,和是否懒加载已经加载

10.JPA访问底层实现的API

Session session = entityManager.unwrap( Session.class );
SessionImplementor sessionImplementor = entityManager.unwrap( SessionImplementor.class );

11.复制对象到不同的数据库

session.replication

不重新生成标识符,直接将持久实例以及其关联的实例一起拷贝到其他数据库

你可能感兴趣的:(Hibernate 持久化上下文总结)