【问题标题】:My Injected sessionFactory instance is null我注入的 sessionFactory 实例为空
【发布时间】:2021-02-02 17:09:26
【问题描述】:

当我使用基于 Java 的 Hibernate 配置注入我的 sessionFactory Bean 时,我的 bean 为空,我不知道为什么。我已经在互联网上搜索了答案,但找不到任何答案。我查看了我的配置并将其与在线指南进行了比较。非常感谢任何答案。

这是确切的错误

线程“main”中的异常 java.lang.NullPointerException:无法调用“org.hibernate.SessionFactory.getCurrentSession()”,因为“com.example.demo.DemoApplication.sessionFactory”为空

这是我的代码

HibernateConfiguration 文件,基于注解。

@Configuration
@EnableTransactionManagement
public class HibernateConfig {

@Bean
@Scope  //By default the scope is singleton which means that the IOC will only create a single instance of the bean and return that one reference for subsequent calls for that bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan( packagesToScan());  //Model packages to scan
    sessionFactory.setHibernateProperties(hibernateProperties());

    return sessionFactory;
}

//Direct Physical Connection Information
@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/demo");
    dataSource.setUsername("root");
    dataSource.setPassword("password");

    return dataSource;
}

@Bean
public PlatformTransactionManager hibernateTransactionManager() {
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());
    return transactionManager;
}
//List of Entities to scan
@Bean
public String [] packagesToScan() {
    return new String [] { "com.example.demo.Entities.Student" };
}
//Configures properties of our hibernate configuration, dialect, 

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

    return hibernateProperties;
}
}

我尝试注入会话工厂单例 bean 以供使用的主应用程序。

@SpringBootApplication
public class DemoApplication {
    
@Autowired
static SessionFactory sessionFactory;
    
public static void main(String[] args) {

    ApplicationContext ctx = new AnnotationConfigApplicationContext(AnimalConfig.class,         HibernateConfig.class); // Makes the sessionFactory bean known to the IOC
    Session currentSession = sessionFactory.getCurrentSession();

    
    (( ConfigurableApplicationContext )ctx).close();  //Close the applicationContext
    SpringApplication.run(DemoApplication.class, args);

}

}

【问题讨论】:

    标签: java spring-boot hibernate


    【解决方案1】:

    容器在 SpringApplication.run 调用时启动。我认为在所有这一切之前,注入和使用该 bean 是没有意义的。首先你需要触发 Springapplication,然后是其余的业务逻辑。

    在注入时不会扫描和初始化您的 bean。

    可能的解决方案:

    @Component
    public class IOCAfterInitializationListener implements ApplicationListener<ContextRefreshedEvent> {
    
    @Autowired
    static SessionFactory sessionFactory;
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent event) {
          Session currentSession = sessionFactory.getCurrentSession();
           //do whatever you want
        }
    }
    

    【讨论】:

    • 我明白了,使用 .getBean() 来获取 sessionFactory 怎么样?我只是想在我的主函数中试验 HQL 查询
    • 你不应该在 SpringBootApplication 类的 main() 中添加任何东西,让 Spring 完成它的工作。通过上面的示例,您可以获得您想要的相同功能。该方法将在 IOCAfterInitializationListener 中在 spring 完成它的工作并且 IOC 容器已准备好使用后直接调用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    相关资源
    最近更新 更多