Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate SessionFactory与JPA EntityManager Factory_Java_Hibernate_Jpa_Sessionfactory_Hibernate Entitymanager - Fatal编程技术网

Java Hibernate SessionFactory与JPA EntityManager Factory

Java Hibernate SessionFactory与JPA EntityManager Factory,java,hibernate,jpa,sessionfactory,hibernate-entitymanager,Java,Hibernate,Jpa,Sessionfactory,Hibernate Entitymanager,我不熟悉Hibernate,我不确定是使用HibernateSessionFactory还是JPAEntityManagerFactory来创建Hibernate会话 这两者有什么区别?使用每种方法的优缺点是什么?首选EntityManager工厂和EntityManager。它们由JPA标准定义 SessionFactory和Session是特定于休眠的。EntityManager在引擎盖下调用hibernate会话。如果您需要一些在EntityManager中不可用的特定功能,您可以通过调用

我不熟悉Hibernate,我不确定是使用Hibernate
SessionFactory
还是JPA
EntityManagerFactory
来创建Hibernate
会话


这两者有什么区别?使用每种方法的优缺点是什么?

首选
EntityManager工厂
EntityManager
。它们由JPA标准定义

SessionFactory
Session
是特定于休眠的。
EntityManager
在引擎盖下调用hibernate会话。如果您需要一些在
EntityManager
中不可用的特定功能,您可以通过调用:

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

我想补充一点,您还可以通过从
EntityManager
调用
getDelegate()
方法来获取Hibernate的会话

例:


使用EntityManagerFactory方法允许我们使用回调方法注释,如@PrePersist、@PostPersist、@PreUpdate,而无需额外配置

在使用SessionFactory时使用类似的回调将需要额外的努力

相关的Hibernate文档可以找到并保存


通过使用EntityManager,代码不再与hibernate紧密耦合。但为此,在使用中,我们应使用:

javax.persistence.EntityManager
而不是

org.hibernate.ejb.HibernateEntityManager

类似地,对于EntityManagerFactory,使用javax接口。这样,代码是松散耦合的。如果有比hibernate更好的JPA2实现,那么切换就很容易了。在极端情况下,我们可以向HibernateEntityManager键入cast

与会话工厂相比,我更喜欢JPA2
EntityManager
API,因为它感觉更现代。一个简单的例子:

JPA:

@PersistenceContext
实体管理器实体管理器;
公共列表查找someapples(){
返回实体管理器
.createQuery(“来自MyEntity,其中Apple=7”,MyEntity.class)
.getResultList();
}
会话工厂:

@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;
}
@Autowired
会话工厂会话工厂;
公共列表查找someapples(){
Session Session=sessionFactory.getCurrentSession();
列表结果=session.createQuery(“来自MyEntity,其中Apple=7”)
.list();
@抑制警告(“未选中”)
List resultCasted=(List)结果;
返回已计算的结果;
}

我认为很明显,第一个看起来更干净,也更容易测试,因为EntityManager很容易被模仿。

EntityManager界面类似于hibernate中的sessionFactory。 EntityManager位于javax.persistence包下,但session和sessionFactory位于org.hibernate.session/sessionFactory包下


实体管理器是特定于JPA的,会话/会话工厂是特定于hibernate的。

EntityManagerFactory是标准实现,在所有实现中都是相同的。如果您将您的ORM迁移到任何其他提供商(如EclipseLink),那么处理事务的方法将不会有任何变化。相反,如果使用hibernate的会话工厂,它与hibernate API绑定,无法迁移到新供应商。

SessionFactory
EntityManagerFactory
正如我在中所解释的,Hibernate
SessionFactory
扩展了JPA
EntityManagerFactory
,如下图所示:

因此,
SessionFactory
也是一个JPA
EntityManagerFactory

会话工厂
EntityManager工厂
都包含实体映射元数据,并允许您创建Hibernate
会话
EntityManager

会话
实体管理器
会话工厂
EntityManager工厂
一样,Hibernate
会话
扩展了JPA
EntityManager
。因此,
EntityManager
定义的所有方法都可以在Hibernate
会话中使用

会话
和`EntityManager将转换为SQL语句,如SELECT、INSERT、UPDATE和DELETE

Hibernate与JPA引导 在引导JPA或Hibernate应用程序时,您有两种选择:

  • 您可以通过Hibernate本机机制引导,并通过创建会话工厂。如果您使用的是Spring,则Hibernate引导是通过
    LocalSessionFactoryBean
    完成的,如所示
  • 或者,您可以通过类或创建一个JPA
    EntityManagerFactory
    。如果您使用的是Spring,那么JPA引导是通过
    LocalContainerEntityManagerFactoryBean
    完成的,如所示
  • 最好通过JPA引导。这是因为JPA
    FlushModeType.AUTO
    比传统的
    FlushMode.AUTO
    要好得多

    展开JPA以休眠 另外,如果您通过JPA引导,并且通过
    @PersistenceUnit
    注释注入了
    EntityManagerFactory

    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;
    
    @PersistenceContext
    private EntityManager entityManager;
    
    您可以使用
    unwrap
    方法轻松访问底层的
    Sessionfactory

    SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
    
    Session session = entityManager.unwrap(Session.class);
    
    JPA
    EntityManager
    也可以执行同样的操作。如果通过
    @PersistenceContext
    注释插入
    EntityManager

    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;
    
    @PersistenceContext
    private EntityManager entityManager;
    
    您可以使用
    展开
    方法轻松访问底层
    会话

    SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
    
    Session session = entityManager.unwrap(Session.class);
    
    结论
    因此,您应该通过JPA引导,使用
    EntityManager工厂
    EntityManager
    ,并且只有当您想要访问JPA中不可用的特定于Hibernate的方法时,才将这些方法打开到其关联的Hibernate接口,比如通过its获取实体。

    @elpisu-实际上,我不推荐。我只使用官方文档作为学习资源(至少在过去的两年中),所以我不知道任何其他可靠的信息。但是这些文件已经足够好了。@Bozho我知道已经很晚了,但是有什么问题吗