Hibernate Sessionfactory VS. JPA Entitymanagerfactory

Hibernate SessionFactory vs. JPA EntityManagerFactory

Prefer EntityManagerFactory and EntityManager. They are defined by the JPA standard.

SessionFactory and Session are hibernate-specific. The EntityManager invokes the hibernate session under the hood. And if you need some specific features that are not available in the EntityManager, you can obtain the session by calling:

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

Hibernate SessionFactory vs EntityManagerFactory

You should prefer the standard JPA API over the proprietary Hibernate one, for several reasons:

  1. It makes you learn something that you can reuse in more other projects, relying on a different implementation
  2. The JPA API is cleaner than the Hibernate one: it doesn't have the early mistakes that the Hibernate API has
  3. The efforts and evolutions are now targeted at the JPA API. For example, the standard JPA2 criteria API is more complete than the old, proprietary, Hibernate Criteria API (but more complex to use, IMHO)
  4. If you want, you can always get the Hibernate Session from the JPA EntityManager. Not vice-versa

Anyway, most of the effort is in mapping the entities themselves, and that is done using standard JPA annotations, even when using the Session API.

Use hibernate sessionFactory or JPA entityManager?

I would stick to JPA2, like you would use List rather than ArrayList: you favour the interface (or abstract) over the implementation. There are not much difference, apart from HQL knowing "more" stuff than JPQL or exotic feature. Also remember that JPA was made after Hibernate, with Hibernate being the "inspiration" behind JPA.

And for exotic feature: Hibernate Entity Manager wrap an Hibernate Session. If you really need them, you can cast the EntityManager to the Hibernate interface (org.hibernate.jpa.HibernateEntityManager), and use that session. But I'd be lying to you if I say I tried it.

I also commented part of your question:

The only reason I would want to use full JPA specifications and the
entityManager is to be able to switch out Hibernate for a different
JPA 2.0 compatible ORM relatively easily, right? Are there really no
performance / functionality / ease of programming benefits to using
the entityManager?

Switching from Hibernate to EclipseLink does not mean you "only need to swap the jar". The mapping, and annotation parsing, is not the same and you'll encounter problems that will probably discourage you from switching.

You can read my question here for an example of a problem I encountered while using both (it was a maven project with a profile to switch JPA2.1 impl from EclipseLink to Hibernate). I dropped EclipseLink because I could not name the database object (or rather, specify the name of database object) like I wanted.

Second, it seems like the hibernate sessionFactory has a lot of
benefits over the entityManager. So far I've run into the issue that
the entityManager can't perform a batch insert of a list of entities,
which I've read the sessionFactory can. I've also read that the
sessionFactory can return an auto-generated entity ID automatically,
while with the entityManager you need to end the transaction / flush
the persistence context to pull the newly generated id.

This depends on how you generate your entity id. But think about it: you entity is not persisted until the persistence context need to persist it. This is the reason you don't have an id. Flushing it, aka sending an insert query with a generated id, is the only way to do it.

The same apply to session factories.

You might however be able to access a sequence generator from Hibernate, but you can also do that in native SQL with EntityManager.

I liked the idea of my project being relatively decoupled from
Hibernate, but I would much rather be able to write efficient database
updates from the get-go. So I should switch over to my project being
configured for hibernate and the sessionFactory, right?

You can take it as a troll against ORM, but for efficient database update, use plain JDBC (or Spring Jdbc Template). At least you'll know when data will be updated, and you'll be able to better optimize (batch update, etc).

Confusion about EntityManagerFactory and SessionFactory with Hibernate 5.3, Spring Data JPA 2.1.4 and Spring 5.1

After some trial-and-error we figured out what was wrong with the configuration. The following (abridged) configuration works:

@Configuration
@EnableJpaRepositories(
basePackages = "com.example.repository",
bootstrapMode = BootstrapMode.DEFERRED
)
@EnableTransactionManagement
@Profile({ "local", "dev", "prod" })
public class DatabaseConfig
{
@Bean
public LocalSessionFactoryBean entityFactoryBean(
final DataSource dataSource
)
{
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();

sessionFactory.setDataSource(dataSource);
sessionFactory.setPackagesToScan("com.example.model");

return sessionFactory;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
{
return new PersistenceExceptionTranslationPostProcessor();
}

@Bean
public HibernateTransactionManager transactionManager(
final SessionFactory sessionFactory,
final DataSource dataSource
)
{
final HibernateTransactionManager transactionManager = new HibernateTransactionManager();

transactionManager.setSessionFactory(sessionFactory);
transactionManager.setDataSource(dataSource);

return transactionManager;
}
}

The LocalSessionFactoryBean can be named entityFactoryBean and Spring is still able to autowire a SessionFactoy for the hibernateTransactionManager.
I hope this helps if anybody else has a similar problem.



Related Topics



Leave a reply



Submit