web-dev-qa-db-fra.com

Spring Boot: erreur lors de la création d'un bean avec le nom 'jpaMappingContext': Java.lang.NullPointerException

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

11
Sudhirkd

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);
    }
}
14
wallance

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.

3
Vishal

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é.

0
IhorP