通过使用EntityManager,代码不再与休眠紧密结合。但是为此,在使用中我们应该使用:
Session session = entityManager.unwrap(Session.class);
我是Hibernate的新手,我不确定是否要使用Hibernate SessionFactory
或JPA EntityManagerFactory
创建Hibernate Session
。
这两者之间有什么区别?使用这些功能的利弊是什么?
优选EntityManagerFactory
和EntityManager
。它们由JPA标准定义。
SessionFactory
和Session
是休眠特定的。 EntityManager
在后台调用休眠会话。并且,如果您需要EntityManager
中不可用的某些特定功能,则可以通过以下方式获取会话:
Session session = entityManager.unwrap(Session.class);
我想补充一点,您也可以通过从getDelegate()
调用EntityManager
方法来获得Hibernate的会话。
ex:
Session session = (Session) entityManager.getDelegate();
我更喜欢JPA2EntityManager
API,而不是SessionFactory
,因为它感觉更现代。一个简单的例子:
JPA:
@PersistenceContext
EntityManager entityManager;
public List<MyEntity> findSomeApples() {
return entityManager
.createQuery("from MyEntity where apples=7", MyEntity.class)
.getResultList();
}
SessionFactory:
@Autowired
SessionFactory sessionFactory;
public List<MyEntity> findSomeApples() {
Session session = sessionFactory.getCurrentSession();
List<?> result = session.createQuery("from MyEntity where apples=7")
.list();
@SuppressWarnings("unchecked")
List<MyEntity> resultCasted = (List<MyEntity>) result;
return resultCasted;
}
我认为很明显,第一个看起来更干净并且也更容易测试,因为EntityManager可以轻松模拟。
SessionFactory
vs. EntityManagerFactory
] >>正如我在Hibernate User Guide中所解释的,Hibernate SessionFactory
扩展了JPA EntityManagerFactory
,如下图所示:
因此,SessionFactory
也是JPA EntityManagerFactory
。
SessionFactory
和EntityManagerFactory
都包含实体映射元数据,并允许您创建休眠Session
或EntityManager
。
Session
vs. EntityManager
] >>就像SessionFactory
和EntityManagerFactory
一样,休眠Session
扩展了JPA EntityManager
。因此,EntityManager
定义的所有方法都可以在Hibernate Session
中使用。
Session
和`EntityManager将entity state transitions转换为SQL语句,例如SELECT,INSERT,UPDATE和DELETE。
引导JPA或Hibernate应用程序时,有两种选择:
SessionFactory
创建一个BootstrapServiceRegistryBuilder
。如果您使用的是Spring,则通过BootstrapServiceRegistryBuilder
完成Hibernate引导,如LocalSessionFactoryBean
所示。EntityManagerFactory
创建JPA Persistence
。如果您使用的是Spring,则JPA引导程序将通过Persistence
完成,如EntityManagerFactoryBuilder
所示。首选通过JPA引导。这是因为JPA EntityManagerFactoryBuilder
比传统的LocalContainerEntityManagerFactoryBean
this GitHub example更好。
此外,如果您通过JPA进行引导,并且已经通过FlushModeType.AUTO
注释注入了FlushMode.AUTO
:
breaks read-your-writes consistency for native SQL queries您可以使用
EntityManagerFactory
方法轻松访问基础@PersistenceUnit
:@PersistenceUnit private EntityManagerFactory entityManagerFactory;
JPA
Sessionfactory
可以执行相同的操作。如果通过unwrap
注释注入SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
:EntityManager
您可以使用
EntityManager
方法轻松访问基础@PersistenceContext
:@PersistenceContext private EntityManager entityManager;
结论
因此,您应该通过JPA进行引导,使用
Session
和unwrap
,并且仅当您想访问JPA中不可用的某些特定于Hibernate的方法时才将它们解包到其关联的Hibernate接口,例如[ C0]。
通过使用EntityManager,代码不再与休眠紧密结合。但是为此,在使用中我们应该使用:
Session session = entityManager.unwrap(Session.class);
而不是
EntityManagerFactory
类似地,对于EntityManagerFactory,请使用javax接口。这样,代码就可以松散耦合。如果有一个比休眠更好的JPA 2实现,则切换将很容易。在极端情况下,我们可以将强制类型转换为HibernateEntityManager。
EntityManagerFactory是标准实现,在所有实现中都相同。如果您将ORM迁移到其他任何提供程序(例如EclipseLink),则处理事务的方法将没有任何变化。相反,如果使用hibernate的会话工厂,则它将与hibernate API绑定在一起,并且无法迁移到新的供应商。
EntityManager接口类似于休眠中的sessionFactory。EntityManager在javax.persistance包下,而session和sessionFactory在org.hibernate.Session / sessionFactory包下。
实体管理器是JPA特定的,而session / sessionFactory是休眠的。
通过使用EntityManager,代码不再与休眠紧密结合。但是为此,在使用中我们应该使用:
Session session = entityManager.unwrap(Session.class);
EntityManagerFactory是标准实现,在所有实现中都相同。如果您将ORM迁移到其他任何提供程序(例如EclipseLink),则处理事务的方法将没有任何变化。相反,如果使用hibernate的会话工厂,则它将与hibernate API绑定在一起,并且无法迁移到新的供应商。
EntityManager接口类似于休眠中的sessionFactory。EntityManager在javax.persistance包下,而session和sessionFactory在org.hibernate.Session / sessionFactory包下。
实体管理器是JPA特定的,而session / sessionFactory是休眠的。