I'm creating a standalone Java application that uses Spring Data with JPA.
Part of the class that creates the factory for the EntityManagerFactory is below:
@Configuration
@Lazy
public class JpaConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(MultiTenantConnectionProvider connProvider, CurrentTenantIdentifierResolver tenantResolver) {
...
}
The problem is: I can only detect the Hibernate Dialect after the ApplicationContext is initialized, because this information is read from an external configuration service.
Since @Lazy did not work, is there any strategy to avoid creating this bean before it is used, i.e, only create it when another bean injects an instance of EntityManager?
I stumbled upon this issue recently and found a solution that worked. Unfortunately "container" managed beans will be initialized during startup and @Lazy is ignored even if the EntityManager is not injected anywhere.
I fixed it by using an in-memory H2 DB to construct the factory bean during startup and changed it later. I think here's what you can do for your issue.
pom.xml:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
Source code:
@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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With