How Spring @Autowired binds the SessionFactory object even if there is no SessionFactory instance available

Tags: , , , ,



I’m using Hibernate and Spring with Java-based configurations. My config file is this one:

@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
   HibernateTransactionManager txManager = new HibernateTransactionManager();
   txManager.setSessionFactory(s);
   return txManager;
}

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(new String[] { "dto" });
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
 }

Working fine. No problem with this, but when I manually try to set the sessionfactory parameter for trasactionManager, like this:

@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
   HibernateTransactionManager txManager = new HibernateTransactionManager();
   txManager.setSessionFactory(sessionFactory());
   return txManager;
}

The IDE is showing:

`The method setSessionFactory(SessionFactory) in the type HibernateTransactionManager is not applicable for the arguments (LocalSessionFactoryBean)`

So, I created a sessionFactory like below

@Bean
@Autowired
public SessionFactory sessionFactory(DataSource dataSource) {
    LocalSessionFactoryBuilder sessionFactory = new LocalSessionFactoryBuilder(dataSource);
    sessionFactory.addProperties(hibernateProperties());
    sessionFactory.scanPackages("dto");
    return sessionFactory.buildSessionFactory();

}

and passed to trasactionManager It worked.

My question is how spring autowired the sessionFactory object even if there is no no sessionFactory instance present in the 1st approach?

Answer

You need to change the method return types from SessionFactory to HibernateTransactionManager.

This is how it should look like:

@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
   HibernateTransactionManager txManager = new HibernateTransactionManager();
   txManager.setSessionFactory(s);
   return txManager;
}

@Bean
public SessionFactory sessionFactory() {
    Properties properties = new Properties();
    properties.setProperty("hibernate.show_sql", "true")
    properties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory")
    properties.setProperty("hibernate.cache.use_query_cache", "true")
    properties.setProperty("hibernate.cache.use_second_level_cache", "true")
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect")

    return new LocalSessionFactoryBuilder(dataSource())
        .scanPackages("dto")
        .addProperties(properties)
        .buildSessionFactory();
}


Source: stackoverflow