JPA,即Java Persistence API,是JavaEE中的一种orm标准,被视为一套接口。Hibernate等ORM引擎实现了这一标准。其中,EntityManager是一个接口,它提供了对象持久化的核心API。常用的EntityManager实现有两个:Hibernate Session和单例注入的代理EntityManager。Hibernate Session真正实现了接口功能,而代理EntityManager会从当前事务上下文中找到正确的EntityManager,并代理其功能。实际上,我们直接使用的是代理EntityManager,间接使用了Hibernate Session。例如,open-session-in-view和“开启事务”都会在当前线程上下文中设置一个EntityManager,代理EntityManager在执行方法时会找到并调用它。如果当前线程上下文中不存在EntityManager,会报错。EntityManager内部不一定开启了事务,并且它可能被复用。例如,open-session-in-view中创建的EntityManager就没有开始事务,该EntityManager可能在后续开启事务时被复用,并且在事务结束后也不会被销毁。在没有open-session-in-view的情况下,开启一个新事务就会在当前线程上下文中创建一个新的EntityManager,事务结束后会销毁自身创建的EntityManager。EntityManager提供的API比Repository灵活,并可以完成所有持久化需求。以下介绍EntityManager中常用的API及其使用上的细节:persist(Object entity)必须在事务中调用,大概是一个Save的效果,将对象持久化。参数entity不能是Detached状态(游离态),一般用于新增。不会立即发出insert语句。merge(Object entity)必须在事务中调用,大概是一个SaveOrUpdate的效果,会根据参数entity的id立刻做一次select,如果查询到记录,则将entity的属性覆盖上去,不会立即发送update语句。如果没有查询到记录,会新增一个entity,不会立即发送insert语句。返回持久态的entity,该entity可能与传入的参数entity不同。remove(Object entity)必须在事务中调用,从数据库中删除,参数entity必须是持久化对象,不会立即发送delete语句。对被remove的entity做修改,无法保存到数据库中。尽量不要修改被remove过的entity。find(Class entityClass, Object primaryKey)根据id查找对象flush()在事务中调用,会把session中持久化对象的状态同步到数据库中,会在此时发送sql语句到数据库。事务结束前会自动flush。某些查询API在执行前也会自动flush,以保证查询到正确的结果。public Query createQuery(String qlString)public TypedQuery createQuery(String qlString, Class resultClass)执行jpql语句,返回执行结果,执行前会自动调用flush。public Query createNativeQuery(String sqlString)public Query createNativeQuery(String sqlString, Class resultClass)public Query createNativeQuery(String sqlString, String resultSetMapping)执行原生sql,返回结果,执行前会自动调用flush。entity的三种状态瞬时态,直接new出来的,而且没有id。不存在于session中。游离态,通常是new出来的,不存在于session中。但是有id,并且这个id在数据库中存在。持久态,通常是orm引擎查询或save update后返回的对象。存在于session中,有id。由于session(EntityManager)缓存的存在,在事务中,尽可能早地使用持久态对象,可以避免发生一些意外情况。