Hibernate SessionFactory vs. JPA EntityManagerFactory

后端 未结 8 2258
清歌不尽
清歌不尽 2020-11-27 09:03

I am new to Hibernate and I\'m not sure whether to use a Hibernate SessionFactory or a JPA EntityManagerFactory to create a Hibernate Session

8条回答
  •  清酒与你
    2020-11-27 09:21

    SessionFactory vs. EntityManagerFactory

    As I explained in the Hibernate User Guide, the Hibernate SessionFactory extends the JPA EntityManagerFactory, as illustrated by the following diagram:

    So, the SessionFactory is also a JPA EntityManagerFactory.

    Both the SessionFactory and the EntityManagerFactory contain the entity mapping metadata and allow you to create a Hibernate Session or a EntityManager.

    Session vs. EntityManager

    Just like the SessionFactory and EntityManagerFactory, the Hibernate Session extends the JPA EntityManager. So, all methods defined by the EntityManager are available in the Hibernate Session.

    The Session and the `EntityManager translate entity state transitions into SQL statements, like SELECT, INSERT, UPDATE, and DELETE.

    Hibernate vs. JPA bootstrap

    When bootstrapping a JPA or Hibernate application, you have two choices:

    1. You can bootstrap via the Hibernate native mechanism, and create a SessionFactory via the BootstrapServiceRegistryBuilder. If you're using Spring, the Hibernate bootstrap is done via the LocalSessionFactoryBean, as illustrated by this GitHub example.
    2. Or, you can create a JPA EntityManagerFactory via the Persistence class or the EntityManagerFactoryBuilder. If you're using Spring, the JPA bootstrap is done via the LocalContainerEntityManagerFactoryBean, as illustrated by this GitHub example.

    Bootstrapping via JPA is to be preferred. That's because the JPA FlushModeType.AUTO is a much better choice than the legacy FlushMode.AUTO, which breaks read-your-writes consistency for native SQL queries.

    Unwrapping JPA to Hibernate

    Also, if you bootstrap via JPA, and you have injected the EntityManagerFactory via the @PersistenceUnit annotation:

    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;
    

    You can easily get access to the underlying Sessionfactory using the unwrap method:

    SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
    

    The same can be done with the JPA EntityManager. If you inject the EntityManager via the @PersistenceContext annotation:

    @PersistenceContext
    private EntityManager entityManager;
    

    You can easily get access to the underlying Session using the unwrap method:

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

    Conclusion

    So, you should bootstrap via JPA, use the EntityManagerFactory and EntityManager, and only unwrap those to their associated Hibernate interfaces when you want to get access to some Hibernate-specific methods that are not available in JPA, like fetching the entity via its natural identifier.

提交回复
热议问题