3
votes

I've created a Spring Boot web application with IntelliJ using Thymeleaf and Hibernate. I've come so far that I can create all the db connections and it's working fine. As far as I've seen it would be a good way to have the Sessionfactory as a bean and autowire it in all Service Classes which do the db actions.

I have a SpringMvcConfiguration as configuration file which looks like this:

package eu.barz.familykurse.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;


@Configuration
public class SpringMvcConfiguration extends WebMvcConfigurerAdapter{
    @Bean
    public LocaleResolver localeResolver(){
        SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
        sessionLocaleResolver.setDefaultLocale(Locale.GERMAN);
        return sessionLocaleResolver;
    }

    @Bean
    LocaleChangeInterceptor localeChangeInterceptor(){
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("lang");
        return  localeChangeInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry interceptorRegistry){
        interceptorRegistry.addInterceptor(localeChangeInterceptor());
    }
}

Question: I've tried a lot but I could not find a solution to declare the bean for the SessionFactory.

Any hints would be really helpful. Should I declare a sessionfactory and datasource here or does it have to be in application.properties or only in hibernate.cfg.xml which looks currently like this:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/family_kurse</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">username</property>
        <property name="connection.password">secret</property>

        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.current_session_context_class">thread</property>
        <property name="show_sql">true</property>
        <mapping class="eu.barz.familykurse.domain.Leader"/>
        <mapping class="eu.barz.familykurse.domain.Course"/>

        <!-- DB schema will be updated if needed -->
        <!-- <property name="hbm2ddl.auto">update</property> -->
    </session-factory>
</hibernate-configuration>

Cheers Maik

Solution:

  1. I needed to add the beans as mentioned below

  2. I had to add

    org.springframework spring-orm 4.3.10.RELEASE to my pom.xml

  3. After @SpringBootApplication I had to add

    @EnableAutoConfiguration(exclude = {HibernateJpaAutoConfiguration.class})

3

3 Answers

4
votes

Since you are using spring boot you should use XML free configuration for your database configuration . To integrate spring boot with hibernate you will need to create LocalSessionFactoryBean , DataSource ,HibernateTransactionManager and PersistenceExceptionTranslationPostProcessor bean like this:

@Configuration
public class DatabaseConfig {

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan("com.example.model");
        sessionFactory.setHibernateProperties(hibernateProperties());

        return sessionFactory;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/testdb");
        dataSource.setUsername("root");
        dataSource.setPassword("root");

        return dataSource;
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {

        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory);

        return txManager;
    }

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

    Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.ddl-auto", "update");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        return properties;
    }
}

In the above database config i have used postgreSQL database .

To get instance of sessionFactory autowire SessionFactory interface like this:

 @Autowired
 SessionFactory sessionFactory;
0
votes

I have taken this example from here.

@Bean
   public LocalSessionFactoryBean sessionFactory() {
      LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
      sessionFactory.setDataSource(restDataSource());
      sessionFactory.setPackagesToScan(
        new String[] { "org.baeldung.spring.persistence.model" });
      sessionFactory.setHibernateProperties(hibernateProperties());

      return sessionFactory;
   }

   @Bean
   public DataSource restDataSource() {
      BasicDataSource dataSource = new BasicDataSource();
      dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
      dataSource.setUrl(env.getProperty("jdbc.url"));
      dataSource.setUsername(env.getProperty("jdbc.user"));
      dataSource.setPassword(env.getProperty("jdbc.pass"));

      return dataSource;
   }
0
votes

Have you tried this?

@Bean
public org.springframework.orm.hibernate5.LocalSessionFactoryBean sessionFactory(){
    org.springframework.orm.hibernate5.LocalSessionFactoryBean sessionFactory = new org.springframework.orm.hibernate5.LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    return sessionFactory;
}
@Bean
public DataSource dataSource() {

  BasicDataSource dataSource = new BasicDataSource();
  dataSource.setDriverClassName("jdbc.driverClassName");
  dataSource.setUrl("jdbc.url");
  dataSource.setUsername("jdbc.user");
  dataSource.setPassword("jdbc.pass");

  return dataSource;
}