简体   繁体   中英

NullPointerException getting hibernate session

I am trying to integrate Hibernate 5.2.12 into my Spring application but am getting a nullPointerException when get a session.

Here is the Hibernate configuration

@Configuration
@EnableTransactionManagement
public class HibernateConfig {

@Bean
public LocalSessionFactoryBean sessionFactory() {
    System.out.println("Session factory called!");
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(
            "com.app.persistence.model");
    sessionFactory.setHibernateProperties(hibernateProperties());

    return sessionFactory;
}

@Bean
public DataSource dataSource() {

    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/appDatabase?useSSL=false");
    dataSource.setUsername("root");
    dataSource.setPassword("password");

    return dataSource;
}

@Bean
public PlatformTransactionManager hibernateTransactionManager() {
    HibernateTransactionManager transactionManager
            = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());

    return transactionManager;
}

private final Properties hibernateProperties() {
    Properties hibernateProperties = new Properties();
    hibernateProperties.setProperty(
            "hibernate.hbm2ddl.auto", "");
    hibernateProperties.setProperty(
            "hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");

    return hibernateProperties;
}

}

Here is the my util class where sessionFactory is @AutoWired

public class AppHibernateUtil {

private static final AppHibernateUtil instance = new AppHibernateUtil();

@Autowired
private SessionFactory sessionFactory;

public static Session getSession() {

    return getInstance().sessionFactory.openSession();
}

private static AppHibernateUtil getInstance() {
    return instance;
}

}

Here's my attempted usage of a session

public static String getRoles() {

    System.out.println("Custom: getRoles() called");

    List<RoleEntity> roles = new ArrayList<>();

    try(Session session = AppHibernateUtil.getSession()){

        roles = session.createQuery("from RoleEntity").list();
    }

    return gson.toJson(roles.size());
}

public static void main(String args[]) {
    System.out.println(getRoles());
}

The null exception is thrown here

return getInstance().sessionFactory.openSession();

This line never gets outputted at the console

System.out.println("Session factory called!");

If I ignore the AppHibernateUtil class by creating a test class which injects (or not) the sessionFactory. I get the same NPE

@Component
public class TestController {

private static Gson gson = new Gson();

@Autowired
private static SessionFactory sessionFactory;

public static String getRoles() {

    System.out.println("Custom: getRoles() called");

    List<RoleEntity> roles = new ArrayList<>();

    try(Session session = sessionFactory.getCurrentSession()){

        roles = session.createQuery("from RoleEntity").list();
    }

    return gson.toJson(roles.size());
}

public static void main(String args[]) {
    System.out.println(getRoles());
}
}

Problem is not in your hibernate configuration, but in your dependency injection.

You are creating manually singleton of AppHibernateUtil (you are calling new AppHibernateUtil() ), let Spring do its job and annotate AppHibernateUtil with @Component (default scope of component is Singleton), then inject it into you class, where is your session needed.

My guess is that the NPE is being thrown because the sessionFactory in the getSession() method is null.

This means that Spring is not injecting an instance of SessionFactory .

That may be because you've chosen to implemented the AppHibernateUtil as a singleton. I won't disgress into a discussion about that, except that's it's relevant to point out that Spring is based on dependency injection and using singletons goes against that approach.

If you want to keep using a singleton, you may have success with additional annotations on the AppHibernateUtil class:

@Configuration
@ComponentScan("com.your.package.HibernateConfig")
public class AppHibernateUtil {
...
}

However, as described in the docs , it would probably be best to refactor the AppHibernateUtil class so that it was not a singleton:

@Configuration
public class AppHibernateUtil {
    private final AppConfig appConfig;

    public AppHibernateUtil(AppConfig appConfig) {
         this.appConfig = appConfig;
     }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM