NullPointerException获取休眠会话

时间:2019-02-14 14:16:58

标签: java spring hibernate

我正在尝试将Hibernate 5.2.12集成到我的Spring应用程序中,但是在获取会话时却收到nullPointerException。

这是Hibernate配置

@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;
}

}

这是我的util类,其中sessionFactory为@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;
}

}

这是我尝试使用的会话

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());
}

此处将引发null异常

return getInstance().sessionFactory.openSession();

此行永远不会在控制台上输出

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

如果我通过创建一个注入(或不注入)sessionFactory的测试类来忽略AppHibernateUtil类。我得到相同的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());
}
}

2 个答案:

答案 0 :(得分:1)

问题不在您的休眠配置中,而是在您的依赖项注入中。

您正在手动创建AppHibernateUtil的单例(您正在调用@Component),让Spring进行其工作并用if (t >= 0.5) { d = -1; } else if (t <= 0){ d = 1; } t += 0.01f * d; // increment movement variable 注释AppHibernateUtil(组件的默认范围是Singleton),然后将其注入到您的类中,您的会话需要在哪里。

答案 1 :(得分:1)

我的猜测是,由于sessionFactory方法中的getSession()为空,因此引发了NPE。

这意味着Spring不会注入SessionFactory的实例。

这可能是因为您选择将AppHibernateUtil实施为单例。除了要指出的是,Spring是基于依赖项注入的,并且使用单例的做法与该方法背道而驰之外,我将不进行讨论。

如果您想继续使用单例,则可以在AppHibernateUtil类上添加其他注释来获得成功:

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

但是,如docs中所述,最好重构AppHibernateUtil类,使其不是单例:

@Configuration
public class AppHibernateUtil {
    private final AppConfig appConfig;

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