私の組み合わせは、Spring Boot + Spring Data Jpa + Multiple Databasesです。アプリケーションを起動すると、次のNullPointer例外が発生します。 SPring Data with BootはJPAメタデータを生成できないように感じます。このエラーに関連するリソースを取得できませんでした。
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is Java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:736)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.Java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:946)
at com.verient.infinipay.staticcard.Application.main(Application.Java:25)
... 6 more
Caused by: Java.lang.NullPointerException
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.getMetamodels(JpaMetamodelMappingContextFactoryBean.Java:90)
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.Java:56)
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.Java:26)
at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.Java:134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.Java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1570)
... 21 more
私のコードは:
public EntityManagerFactory apEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(apDataSource())
.packages(Entity1.class, Entity2.class)
.persistenceUnit("ap-persistent-unit")
.build()
.getObject();
}
@Bean
public EntityManagerFactory trEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(trDataSource())
.packages(Entity3.class, Entity4.class)
.persistenceUnit("tr-persistent-unit")
.build()
.getObject();
}
@Bean
JpaTransactionManager apTransactionManager(@Qualifier("apEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
JpaTransactionManager trTransactionManager(@Qualifier("trEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
また、application.propertiesに次のhibernateプロパティがあります。
spring.jpa.hibernate.ddl-auto: update
spring.jpa.hibernate.naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.database: H2
spring.jpa.show-sql: true
Springブートでは、クラスパスで既に準備されているデータソースに対してデフォルトでAutoConfigurationクラスが有効になっています。 AutoConfigurationクラスを明示的に除外して無効にする必要があります。
例:
@EnableAutoConfiguration(exclude = {JndiConnectionFactoryAutoConfiguration.class,DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,JpaRepositoriesAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class})
@ComponentScan
public class MyBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyBootApplication.class, args);
}
}
私にとってこれは、JSONタイプをJavaオブジェクトにマッピングするために使用していたorg.hibernate.usertype.UserType
のカスタム実装によるものであることが判明しました。
私の特定のケースでは、Java.util.Mapへのマッピングであり、この Spring Data JPAの変更 は、そのバージョンへのアップグレード時にリグレッションを引き起こしていました。
修正は、マップのジェネリックタイプを明示的に設定することでした。 Map<String, Object>
私の場合。
Vishalのアイデアに感謝します。私の場合、この例外を引き起こしたのはjavax.persistence.AttributeConverter
のジェネリックレス実装でした。 class MapConverter implements AttributeConverter<Map, String> { ... }
をclass MapConverter implements AttributeConverter<Map<String, Object>, String> { ... }
に変更すると本当に役立ちました。