【问题标题】:Spring boot 2.1 and Hibernate 5.3 SessionFactory not Autowired when annotating the Dao classes with @Repository使用 @Repository 注释 Dao 类时,Spring boot 2.1 和 Hibernate 5.3 SessionFactory 未自动装配
【发布时间】:2019-06-23 09:59:49
【问题描述】:

当我在使用@Repository spring 注释注释的 Dao 实现中自动连接休眠会话工厂时,它无法创建 SessionFactory 和 Dao bean,但是它在没有 @Repository 注释的情况下工作。

我搜索了很多问题和答案,但都与早期版本的 hibernate 和 spring boot 相关,例如 unwrap 和创建会话工厂 bean,但所有这些方法都与 spring-boot 2.1 和最新的 Hibernate 版本不兼容。

在 Spring Boot 2.1 和最新的休眠版本 (5.3) 中是否有任何特定的方法来创建和自动装配休眠会话工厂?

@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private SessionFactory sf;

    @Override
    public void addUser(User user) {
        Session session = sf.getCurrentSession();
        session.save(user);
    }


}

在上面的代码中,SessionFactory 在没有@Repository 的情况下自动连接,我用下面的 bean 创建了一个配置类

@Configuration
public class DataConfig {
    @Bean
    public SessionFactory sessionFactory(@Autowired EntityManagerFactory factory) {
            if (factory.unwrap(SessionFactory.class) == null) {
                throw new NullPointerException("factory is not a hibernate factory");
            }
            return factory.unwrap(SessionFactory.class);
    }

}

它当然“应用上下文中某些bean的依赖形成了一个循环:”错误

【问题讨论】:

  • 为什么要用SessionFactory,我建议改成EntityManager,用persist instead. The error is coming from the fact that as of Hibernate 5.2 the SessionFactory`扩展EntityManagerFactory。这将禁用 EntityManagerFactory 的 Spring 引导自动配置,现在您拥有从 SessionFactorySessionFactory 的依赖关系,因为这也是 EntityManagerFactory
  • 你也可以从EntityManager解开SessionFactory

标签: java spring spring-boot


【解决方案1】:
@Bean
public SessionFactory sessionFactory() {
    LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource());
    sessionBuilder.scanPackages("com.your.domain.package");
    return sessionBuilder.buildSessionFactory();
}

@Bean
public DataSource dataSource() {
    final HikariConfig config = new HikariConfig();
    config.setMinimumIdle(Integer.valueOf(env.getProperty("spring.datasource.minimumIdle")));
    config.setMaximumPoolSize(Integer.valueOf(env.getProperty("spring.datasource.maximumPoolSize")));
    config.setIdleTimeout(Integer.valueOf(env.getProperty("spring.datasource.idleTimeout")));
    config.setConnectionTestQuery("SELECT 1");
    config.setDataSourceClassName(env.getProperty("spring.datasource.className"));
    config.addDataSourceProperty("url", env.getProperty("spring.datasource.url"));
    config.addDataSourceProperty("user", env.getProperty("spring.datasource.username"));
    config.addDataSourceProperty("password", env.getProperty("spring.datasource.password"));
    return new HikariDataSource(config);
}

@Mr.体面,以这种方式更改您的配置以解决此问题。

【讨论】:

  • 为什么我们使用这个显式的 hikari 配置,spring boot 2.x 自带 hikari 作为默认的数据源实现,如果我们想在基于 Spring Boot 2 的应用程序中使用 Hikari,我们什么都做不了。 x
  • 它不是强制性的,您可以使用也可以不使用。
  • 为什么 Spring-boot 自动配置没有自动连接自动配置的默认数据源(hikari)并创建这个,上面的配置也破坏了 JPA EntityManagerFactory。
  • @Mr.Decent 如果你想实现这一点,只需在你的 Repository 类中使​​用 Autowire EntirtyManager。
  • 你不需要DataSource的配置,Spring Boot会为你配置一个。 SessionFactoryEntityManagerFactory,因此从 Hibernate 5.3 开始可以互换。尽管如此,我还是建议您使用 EntityManager 而不是 SessionFactorySession,因为如今 JPA 的当前状态几乎不需要这样做。
猜你喜欢
  • 2017-10-09
  • 2015-05-27
  • 2016-10-03
  • 2012-06-10
  • 2018-10-25
  • 2018-11-02
  • 2011-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多