实体对象是@Entity 类型的类在内存中的实例对象,也是存储在物理数据库中的对象在内存中的表现形式。
采用JPA规范去管理对象数据库,需要执行许多操作,包括存储、检索、更新、删除对象等
实体对象的生命周期有四种状态:创建、托管、删除、分离
当一个@Entity类型的实例刚被创建后,并未和EntityManager产生管理,在DB中也没有相应形式的数据表示。
当通过EntityManager的persist 方法将一个Entity 对象持久化到DB后,此对象就处于被此EntityManager托管的状态了,当然persist方法的执行必须是在一个活动事务内完成的。事务一旦提交,对象就物理地存储到DB中了。
通过EntityManager检索出的对象也都处于被此EntityManager托管的状态。
如果在一个活动事务内,对象被更新了,那么此事务所属的EntityManager会检测到更新,并且在事务提交时将更新传播到数据库。
通过在一个活动的EntityTransaction内调用EntityManager的remove方法,处于托管状态的对象就能被检索到并将其标记为删除状态。一旦commit后,DB将物理删除此对象。
分离状态,表示对象不再关联到EntityManager。例如当EntityManger被关闭后,所有被其托管的实体,都将称为分离状态的对象。
persistence context 是一个EntityManager所管理的所有Entity的实例的集合。如果被检索的对象已经处于被EntityManager管理的对象集合中,那么EntityManager将不再去访问DB,而是直接从其所管理的集合中取出对象并返回,除非显式地调用刷新flush功能。
持久化上下文的主要角色是确保DB中的一个实例对象在EntityManager中只有一个内存对象与之对应。但是每个EntityManger都有各自的一个Context,因此DB中的一个实体对象在应用程序内存中可能会存在多个EntityManager的都有一个内存实例。只要确保始终用同一个EntityManger对同一个数据库做检索操作,那么就能确保数据库的一个实体对象在一个应用程序内存中只有一个内存实例。
从另一个角度看,可以认为persist context充当了EntityManager的本地缓存。同时ObjectDB也为EntityManager管理了一个二级缓存。
默认情况下,由于persist context保存的是内存实例的弱应用,如果实例没有被修改或者被remove,那么当应用程序不再使用它(代表对象的变量的生存周期已经结束),就会被垃圾回收。那么下次再由检索时,就需要从DB中取,有时用户可以修改配置,使persist context 保存对象的强引用,或许更符合实际需求。
开发者可以调用em.contains(entity)方法判断一个entity实例是否已经存在于persist context。
调用em.clear()方法来清除EntityManager的persistence context。一旦清除,那么所有托管的对象都与EntityManager分离,对对象的所有未刷新到数据库的更新也都会丢弃。