我正在尝试将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());
}
}
答案 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;
}
}