Hey there, I’ve got:
- A custom IndexLayoutStrategy that I’ve defined. This is a bean in my application context. It uses another bean, which is autowired into it.
- A JpaProperties bean which includes all necessary HS setup, including pointing at my custom index layout strategy.
When I attempt to boot my test scenario, i get:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ca.uhn.fhir.jpa.config.TestR4ConfigWithElasticSearch: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: PU_TEST] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.search.util.common.SearchException: HSEARCH000520: Hibernate Search encountered failures during bootstrap. Failures:
Hibernate ORM mapping:
type 'ca.test.tester.jpa.entity.MyEntity':
failures:
- Cannot invoke "ca.test.tester.jpa.api.config.MyAutowiredBean.someMethod()" because "this.MyAutowiredBean" is null
When I actually breakpoint through the ElasticsearchBackendFactory’s initialization, I see that the BeanResolver.beanManagerBeanProvider is set to NoConfiguredBeanProvider
. This tells me that HS is simply creating a new instance of my class via public constructor, which explains why anything i had set to autowire is null. Below are the salient parts of the code. Any thoughts on what I’m missing here? Below is a sample @Configuration, if i run an empty test with this config, I get the above error:
@Configuration
public class DummyConfig {
@Bean
public MyAutowiredBean autowiredBean() {
return new MyAutowiredBean();
}
@Bean
public MyIndexLayoutStrategy indexLayoutStrategy() {
return new MyIndexLayoutStrategy();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new HapiFhirLocalContainerEntityManagerFactoryBean();
retVal.setJpaDialect(new HibernateJpaDialect());
retVal.setPackagesToScan("ca.test.tester.jpa.model.entity", "ca.test.tester.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setPersistenceUnitName("PU_TEST");
retVal.setDataSource(dataSource());
retVal.setJpaProperties(jpaProperties());
return retVal;
}
@Bean
public DataSource dataSource() {
BasicDataSource retVal = new BasicDataSource();
retVal.setDriver(new org.h2.Driver());
retVal.setUrl("jdbc:h2:mem:testdb_r4");
retVal.setMaxWaitMillis(30000);
retVal.setUsername("");
retVal.setPassword("");
retVal.setMaxTotal(5);
DataSource dataSource = ProxyDataSourceBuilder
.create(retVal)
.build();
return dataSource;
}
@Bean
public Properties jpaProperties() {
Properties extraProperties = new Properties();
extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.dialect", H2Dialect.class.getName());
int httpPort = elasticContainer().getMappedPort(9200);
String host = elasticContainer().getHost();
extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "elasticsearch");
extraProperties.put(BackendSettings.backendKey(ElasticsearchIndexSettings.ANALYSIS_CONFIGURER), HapiElasticsearchAnalysisConfigurer.class.getName());
extraProperties.put(BackendSettings.backendKey(ElasticsearchBackendSettings.HOSTS), host + ":" + httpPort);
extraProperties.put(BackendSettings.backendKey(ElasticsearchBackendSettings.PROTOCOL), "http");
extraProperties.put(HibernateOrmMapperSettings.SCHEMA_MANAGEMENT_STRATEGY, SchemaManagementStrategyName.CREATE.externalRepresentation());
extraProperties.put(BackendSettings.backendKey(ElasticsearchIndexSettings.SCHEMA_MANAGEMENT_MINIMAL_REQUIRED_STATUS_WAIT_TIMEOUT), Long.toString(10000));
extraProperties.put(BackendSettings.backendKey(ElasticsearchIndexSettings.SCHEMA_MANAGEMENT_MINIMAL_REQUIRED_STATUS), IndexStatus.YELLOW.externalRepresentation());
// Need the mapping to be dynamic because of terminology indexes.
extraProperties.put(BackendSettings.backendKey(ElasticsearchIndexSettings.DYNAMIC_MAPPING), "true");
extraProperties.put(HibernateOrmMapperSettings.AUTOMATIC_INDEXING_SYNCHRONIZATION_STRATEGY, "read-sync");
extraProperties.put(BackendSettings.backendKey(ElasticsearchBackendSettings.LOG_JSON_PRETTY_PRINTING), Boolean.toString(true));
extraProperties.put(BackendSettings.backendKey(ElasticsearchBackendSettings.LAYOUT_STRATEGY), MyIndexLayoutStrategy.class.getName());
return extraProperties;
}
@Bean
public ElasticsearchContainer elasticContainer() {
ElasticsearchContainer embeddedElasticSearch = TestElasticsearchContainerHelper.getEmbeddedElasticSearch();
embeddedElasticSearch.start();
return embeddedElasticSearch;
}
}
My apologies for the verboseness, i"m just wondering why there is no bean provider during bootstrapping.