Meine Kombination ist Spring Boot + Spring Data Jpa + Multiple Datenbanken. Beim Starten der Anwendung wird die NullPointer-Ausnahme angezeigt. Fühlt sich an, als ob SPring Data with Boot keine JPA-Metadaten erzeugen kann. Ich habe keine Ressource zu diesem Fehler erhalten.
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
Mein Code lautet:
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;
}
Ich habe auch folgende Eigenschaften für den Ruhezustand in application.properties.
spring.jpa.hibernate.ddl-auto: update
spring.jpa.hibernate.naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.database: H2
spring.jpa.show-sql: true
Für Spring Boot sind AutoConfiguration-Klassen standardmäßig für die Datenquellen aktiviert, die sich bereits im Klassenpfad befinden. Sie sollten die AutoConfiguration-Klasse explizit ausschließen, um sie zu deaktivieren.
Beispiel:
@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);
}
}
Für mich stellte sich heraus, dass dies auf eine benutzerdefinierte Implementierung von org.hibernate.usertype.UserType
zurückzuführen ist, die ich für die Zuordnung von JSON-Typen zu Java-Objekten verwendete.
In meinem speziellen Fall war es eine Zuordnung zu einer Java.util.Map, und diese Änderung in Spring Data JPA verursachte eine Regression beim Upgrade auf diese Version.
Das Update bestand darin, generische Typen für die Map explizit festzulegen - z. Map<String, Object>
in meinem Fall.
Vielen Dank an Vishal für die Idee. In meinem Fall war es die generiklose Implementierung von javax.persistence.AttributeConverter
, die diese Ausnahme auslöste. Das Ändern von class MapConverter implements AttributeConverter<Map, String> { ... }
in class MapConverter implements AttributeConverter<Map<String, Object>, String> { ... }
hat wirklich geholfen.