2

I'm upgrading an existing project to use Spring Data JPA and repositories instead of a few DAOs which query data using Hibernate.

So I managed to create a valid configuration which works:

public class PersistenceConfiguration
{
    (...)

    public DataSource dataSource()
    {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();

        (...)

        return dataSource;
    }

    @Bean( "jpaProperties" )
    public Properties jpaProperties()
    {
        Properties properties = new Properties();

        (...)

        return properties;
    }

    @Bean(name = "entityManagerFactory")
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactory()
    {
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setPersistenceUnitName( "entityManagerFactory" );
        factory.setPackagesToScan( "my.package.domain" );
        factory.setJpaVendorAdapter( getHibernateJpaVendorAdapter() );
        factory.setJpaProperties( jpaProperties() );
        factory.setDataSource( dataSource() );

        return factory;
    }

    @Bean( name = "transactionManager" )
    public PlatformTransactionManager transactionManager( EntityManagerFactory entityManagerFactory )
    {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory( entityManagerFactory );
        return txManager;
    }

    protected HibernateJpaVendorAdapter getHibernateJpaVendorAdapter()
    {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl( false );
        vendorAdapter.setDatabase( (this.databasePlatform.contains( "MySQL" ) ? Database.MYSQL : Database.H2) );
        vendorAdapter.setDatabasePlatform( this.databasePlatform );
        return vendorAdapter;
    }

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

As you can see I have used LocalContainerEntityManagerFactoryBean - I have followed a Baeldung tutorial and LocalEntityManagerFactoryBean is another option but tutorial's author claims it is "less flexible". Then I have started digging deeper just to understand how Spring Data JPA works and I found out that there is a third way - LocalSessionFactoryBean.

I guess I could not bother and just stick to whatever works, but I'm quite new to Spring and I would like to avoid copy-pasting code without at least trying to understand it.

Here is what I have found out so far:

LocalSessionFactoryBean:

If I use it, I can access SessionFactory and query data using Hibernate.

Official documentation says:

... and Hibernate BeanContainer integration will be registered out of the box.

Is it what make SessionFactory bean available? I shouldn't use LocalSessionFactoryBean if I don't need accessing SesionFactory?

LocalContainerEntityManagerFactoryBean vs LocalEntityManagerFactoryBean:

I have found a discussion with the explaination how they differ here, but even though a few concepts there aren't clear to me, I understand that for my small self-contained I could stick to LocalEntityManagerFactoryBean. Quick change from to LocalEntityManagerFactoryBean reveals that it doesn't have #setPackagesToScan and #setDataSource methods.

For former, does it mean that the whole app's package tree is being scanned automatically?

What's about #setDataSource - will it just pick up DataSource bean automatically or should I just stick LocalContainerEntityManagerFactoryBean?

What's the purpose of LocalEntityManagerFactoryBean in the first place?

Jonathan Drapeau
  • 2,610
  • 2
  • 26
  • 32
Krzysztof Skrzynecki
  • 2,345
  • 27
  • 39
  • 1
    As explained in the javadoc, LocalEntityManager is used when you want to stick with the standard standalone JPA bootstrap mechanism (based on persistence.xml). If you want entity scanning, being able to configure and set a datasource, etc., then use LocalContainerEntityManagerFactoryBean. LocalSessionFactoryBean is used when you don't want to use JPA, but instead use the proprietary Hibernate API. – JB Nizet Jul 04 '19 at 17:02
  • Thank you for your comment but you aren't right about LocalSessionFactoryBean - "LocalSessionFactoryBean is an immediate alternative to LocalContainerEntityManagerFactoryBean for common JPA purposes: In particular with Hibernate 5.3, the Hibernate SessionFactory will natively expose the JPA EntityManagerFactory interface as well". I need to admit though I didn't understand the difference between `LocalContainerEntityManagerFactoryBean` and `LocalEntityManagerFactoryBean` and bootstrap mechanism when I read the documentation for the first time. – Krzysztof Skrzynecki Jul 04 '19 at 19:17

0 Answers0