Inzo
Inzo

Reputation: 180

spring boot 2. @Bean method invoked before injecting @Autowired dependency

This is just curiosity. In example below @Autowired EntityManagerFactory and @Autowired ApplicationContext are injected before @Bean entityManager() method.

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Autowired
    private ApplicationContext context;


    @Bean
    public EntityManager entityManager() {

        EntityManager entityManager = entityManagerFactory.createEntityManager();
        return entityManager;
    }

}

But when i change EntityManager bean type to SessionFactory then sessionFactory() method is invoked before autowiring EntityManagerFactory and ApplicationContext beans causing NullPointerException when unwrapping SessionFactory. Code snippet below

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Autowired
    private ApplicationContext context;


    @Bean
    public SessionFactory sessionFactory() {

        EntityManager entityManager = entityManagerFactory.createEntityManager();
        return entityManager.unwrap(SessionFactory.class);
    }

}

And my question is: Why is this happening?

Upvotes: 0

Views: 539

Answers (2)

M. Deinum
M. Deinum

Reputation: 124441

As of Hibernate 5.2 the SessionFactory is also an EntityManagerFactory as it now extends said interface. Prior to this the SessionFactory was wrapping an EntityManagerFactory.

Due to this the EntityManagerFactory cannot be injected because the SessionFactory is the actual bean implementing that interface.

Upvotes: 1

Tahir Hussain Mir
Tahir Hussain Mir

Reputation: 2626

As far as i remember there are two ways to obtain the SessionFactory:
From EntityManagerFactory

return entityManagerFactory.unwrap(SessionFactory.class)
//or -> if you have entitymanager
return em.getEntityManagerFactory().unwrap(SessionFactory.class);

From Session

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


And the reasons you are curious like as you said

sessionFactory() method is invoked before autowiring EntityManagerFactory and ApplicationContext beans causing NullPointerException

This is not the case

Upvotes: 1

Related Questions