如何使用Spring Data ORM / JPA延迟创建EntityManagerFactory?

时间:2016-09-14 12:54:57

标签: java spring spring-data-jpa

我正在创建一个将Spring Data与JPA结合使用的独立Java应用程序。

为EntityManagerFactory创建工厂的类的一部分如下:

@Configuration
@Lazy
public class JpaConfig {

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(MultiTenantConnectionProvider connProvider,  CurrentTenantIdentifierResolver tenantResolver) {
...
}

问题是:我只能在初始化ApplicationContext后检测Hibernate Dialect,因为这些信息是从外部配置服务中读取的。

由于@Lazy不起作用,是否有任何策略可以避免在使用它之前创建它,即只在另一个bean注入EntityManager实例时才创建它?

1 个答案:

答案 0 :(得分:0)

我最近偶然发现了这个问题,并找到了可行的解决方案。不幸的是,即使未将@Lazy注入任何地方,“容器”托管Bean也会在启动期间初始化,并且EntityManager会被忽略。

我通过在启动期间使用内存中的H2 DB来构造工厂bean来修复它,并在以后进行了更改。我认为这是您可以解决的问题。

pom.xml:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.199</version>
</dependency>

源代码:

@Configuration
public class DataSourceConfig {

    @Bean
    public HikariDataSource realDataSource() {
        ...
    }

    @Bean
    public DataSource localH2DataSource() {
        return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean myEntityManagerFactory() throws PropertyVetoException {
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        
        factoryBean.setDataSource(localH2DataSource());

        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setShowSql(true);
        factoryBean.setJpaVendorAdapter(jpaVendorAdapter);

        return factoryBean;
    }
}

@Component
@Lazy
public class Main {

    @Autowired
    private LocalContainerEntityManagerFactoryBean emf;

    @Autowired
    private HikariDataSource realDataSource;

    @PostConstruct
    private void updateHibernateDialect() {
        // read the external config here
        emf.setDataSource(realDataSource);
        
        Properties jpaProperties = new Properties();
        jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.DB2Dialect");
        factoryBean.setJpaProperties(jpaProperties);
    }
}