Ma combinaison est Spring Boot + Spring Data Jpa + Plusieurs bases de données. Je reçois une exception NullPointer après le démarrage de l'application. On dirait que SPring Data with Boot n'est pas capable de générer des métadonnées JPA. Je n'ai reçu aucune ressource liée à cette erreur.
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
Mon code est:
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;
}
J'ai également les propriétés d'hibernation suivantes dans 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
Les classes de configuration automatique sont activées par défaut pour le démarrage printanier pour les sources de données déjà sur classpath. Vous devez explicitement exclure la classe AutoConfiguration pour la désactiver.
Exemple :
@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);
}
}
Pour moi, cela s’est avéré être dû à une implémentation personnalisée de org.hibernate.usertype.UserType
que j’utilisais pour mapper des types JSON à des objets Java.
Dans mon cas particulier, il s'agissait d'un mappage vers Java.util.Map et ce changement dans Spring Data JPA provoquait une régression lors de la mise à niveau vers cette version.
Le correctif consistait à définir explicitement les types génériques pour la carte - par exemple. Map<String, Object>
dans mon cas.
Merci beaucoup à Vishal pour cette idée. Dans mon cas, c'est l'implémentation sans code de javax.persistence.AttributeConverter
qui a provoqué cette exception. Remplacer class MapConverter implements AttributeConverter<Map, String> { ... }
par class MapConverter implements AttributeConverter<Map<String, Object>, String> { ... }
m'a vraiment aidé.