..EntityManager
用于与持久性上下文交互的接口。
EntityManager实例与持久性上下文相关联。 持久化上下文是一组实体实例,其中对于任何持久性实体标识,存在唯一的实体实例。 在持久化上下文中,管理实体实例及其生命周期。 EntityManager API用于创建和删除持久性实体实例,按主键查找实体以及查询实体。
由给定EntityManager实例管理的实例集被定义为持久性单元。 持久性单元定义了应用程序相关或分组的所有类的集合,它们在映射到单个数据库时必须进行排位。
@..PersistenceContext
表示对容器管理的EntityManager及其关联的持久性上下文的依赖关系。
.....createEntityManager()(默认是线程安全的)
创建一个新的应用程序管理的EntityManager。 每次调用此方法时,此方法都会返回一个新EntityManager实例。 isOpen方法将在返回的实例上返回true。
.....internalCreateEntityManager
返回EntityManagerImpl实例
.....EntityManagerImpl
..EntityManager具体实现,这里设置一些默认值(javax.persistence.lock.timeout=-1, org.hibernate.flushMode=AUTO,javax.persistence.cache.retrieveMode=USE,javax.persistence.lock.scope=EXTENDED, javax.persistence.cache.storeMode=USE)
....SessionBuilderImplementor
定义SessionBuilder和Hibernate其他部分之间的内部契约。
.....getSessionFactory()
获取底层的Hibernate SessionFactory。
org.hibernate.internal.SessionFactoryImpl
SessionFactory接口的具体实现。 有以下责任
•缓存配置设置(不可变)
•缓存“编译”映射,即。 EntityPersisters和CollectionPersisters(不可变)
•缓存“已编译”的查询(内存敏感缓存)
•管理PreparedStatements
•将JDBC连接管理委派给ConnectionProvider
•工厂用于SessionImpl的实例
此类必须对客户端显示为不可变,即使它在封面下执行各种缓存和池化也是如此。 至关重要的是,该类不仅是线程安全的,而且还是高度并发的。 必须非常谨慎地使用同步。
....SessionBuilderImpl
是SessionBuilderImplementor的具体实现,实例化必须要sessionfactory作为入参
..Session
Java应用程序和Hibernate之间的主要运行时接口。这是抽象持久性服务概念的中央API类。
会话的生命周期受逻辑事务的开始和结束的限制。 (长事务可能跨越多个数据库事务。)
Session的主要功能是为映射的实体类的实例提供创建,读取和删除操作。实例可能存在以下三种状态之一:
transient:永不持久,不与任何Session相关联
persistent:与唯一的Session相关联
分离:以前持久化,不与任何Session关联
通过调用save(),persist()或saveOrUpdate()可以使瞬态实例持久化。通过调用delete()可以使持久化实例变为瞬态。 get()或load()方法返回的任何实例都是持久的。可以通过调用update(),saveOrUpdate(),lock()或replicate()使分离的实例持久化。通过调用merge(),瞬态或分离实例的状态也可以作为新的持久实例持久化,save()和persist()导致SQL EXERT,SQL DELETE中的delete()和SQL UPDATE中的update()或merge()。在刷新时检测到对持久实例的更改,并且还会导致SQL UPDATE。 saveOrUpdate()和replicate()导致INSERT或UPDATE。
并不意味着实现者是线程安全的。相反,每个线程/事务应从SessionFactory获取自己的实例。
如果Session实例的持久化类是可序列化的,则它是可序列化的。
典型的例子:
Session sess = factory.openSession();
try {
tx = sess.beginTransaction();
//do some work
...
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
sess.close();
}
如果会话抛出异常,则必须回滚事务并丢弃会话。发生异常后,Session的内部状态可能与数据库不一致。
.....openSession()
获取session
...SessionImpl
具体实现Session。 暴露两个接口:
•与应用程序的会话
•org.hibernate.engine.spi.SessionImplementor到其他Hibernate组件(SPI)
这个类不是线程安全的。
最后总结:创建entitymanager的时候,会调用getsession方法,从而创建一个session