1
votes

UnsatisfiedDependencyException lors de la création du bean MongoTemplate

Utilisation de Mongobee pour la migration avec spring mongo

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.class]: Unsatisfied dependency expressed through method 'mongoTemplate' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoDatabaseFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.class]: Unsatisfied dependency expressed through method 'mongoDatabaseFactory' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo' defined in class path resource [org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb.client.MongoClient]: Factory method 'mongo' threw exception; nested exception is java.lang.NoSuchFieldError: UNSPECIFIED
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:797) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:538) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1304) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1224) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    ... 25 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoDatabaseFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.class]: Unsatisfied dependency expressed through method 'mongoDatabaseFactory' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo' defined in class path resource [org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb.client.MongoClient]: Factory method 'mongo' threw exception; nested exception is java.lang.NoSuchFieldError: UNSPECIFIED
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:797) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:538) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1304) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1224) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:884) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    ... 38 common frames omitted

Exécution de la dépendance du constructeur pour MongoTemplate provoquant l'erreur org.springframework.beans.factory.UnsatisfiedDependencyException: Erreur lors de la création du bean avec le nom ' mongoTemplate '

Voici le code de configuration

@Configuration
public class ProductMigration {
    private final Environment environment;
    private MongoTemplate mongoTemplate;
    private static final Logger logger = LoggerFactory.getLogger(FeteBirdProductApplication.class);

    public ProductMigration(Environment environment, MongoTemplate mongoTemplate) {
        this.environment = environment;
        this.mongoTemplate = mongoTemplate;
    }

    @Bean
    public Mongobee mongobee(){
        logger.info("Starting product migration ...");
        String mongoUri = environment.getProperty("spring.data.mongodb.uri");
        boolean migrationsEnabled = Boolean.parseBoolean(environment.getProperty("app.db.migrations.enabled"));
        Mongobee runner = new Mongobee(mongoUri);
        runner.setEnabled(migrationsEnabled);
        runner.setChangeLogsScanPackage("fete.bird.fetebirdproduct.migration");
        runner.setChangelogCollectionName("migrations");
        runner.setLockCollectionName("migrations_lock");
        runner.setMongoTemplate(this.mongoTemplate);
        logger.info("Product migration completed...");
        return runner;
    }
}

Le problème est causé par la dépendance du constructeur pour MongoTemplate, mais je ne sais pas comment résoudre le problème,

J'ai essayé @Autowired, mais cela n'a pas fonctionné avec le même problème.

 plugins {
    id 'org.springframework.boot' version '2.3.1.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}

group = 'fete.bird'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '14'
compileJava {
    options.compilerArgs += ["--enable-preview"]
}
repositories {
    mavenCentral()
}
ext {
    set('springCloudVersion', "Hoxton.SR6")
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    implementation 'org.springdoc:springdoc-openapi-ui:1.4.3'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    implementation 'org.springframework.cloud:spring-cloud-starter-config'
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'

    compile 'com.github.mongobee:mongobee:0.13'
}
dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

test {
    useJUnitPlatform()
}


2 commentaires

Le java.lang.NoSuchFieldError dans le message d'exception suggère que vous avez des versions incompatibles de certaines dépendances. Je suppose que c'est la version du pilote Java de Mongo qui cause le problème. Pouvez-vous partager le build.gradle complet de votre projet?


@AndyWilkinson Ajout du fichier gradle


4 Réponses :


0
votes

Il semble que vous n'ayez pas créé le bean pour "MongoTemplate"

Créez un bean pour celui-ci et utilisez-le pour définirMongoTemplate pour Mongobee.

Voici l'exemple pour le faire p >

 @Autowired  
 MongoTemplate mongoTemplate;

puis utilisez ceci

@Bean
public Mongobee mongobee(){
    logger.info("Starting product migration ...");
    String mongoUri = environment.getProperty("spring.data.mongodb.uri");
    boolean migrationsEnabled = Boolean.parseBoolean(environment.getProperty("app.db.migrations.enabled"));
    Mongobee runner = new Mongobee(mongoUri);
    runner.setEnabled(migrationsEnabled);
    runner.setChangeLogsScanPackage("fete.bird.fetebirdproduct.migration");
    runner.setChangelogCollectionName("migrations");
    runner.setLockCollectionName("migrations_lock");
    runner.setMongoTemplate(mongoTemplate());
    logger.info("Product migration completed...");
    return runner;
}

Maintenant, vous n'avez pas besoin d'utiliser la dépendance de constructeur et plus tard où vous voulez MongoTemplate vous pouvez utiliser

@Bean
public MongoClient mongo() {
    return new MongoClient("localhost");
}

@Bean
public MongoTemplate mongoTemplate() throws Exception {
   return new MongoTemplate(mongo(), "test");
}

J'espère que cela résoudra votre problème !!


2 commentaires

Ajouté dans la réponse ci-dessous


Cela ne fonctionne pas réellement, car le problème est dû à une incompatibilité entre la version de la bibliothèque Java MongoDB utilisée pour mongobee et Spring Data MongoDB. J'ai écrit une explication avec une explication détaillée de ce problème.



-1
votes

La voici,

@Bean
public MongoClient mongo() {
    return new MongoClient("localhost");
}


0 commentaires

1
votes

La version de Spring Data MongoDB incluse dans Spring Boot 2.3 utilise la version 4 du pilote de Mongo, mais Mongobee dépend de la version 3. Les deux versions ont des coordonnées Maven différentes (ID de groupe et ID d'artefact) donc vous vous retrouvez avec les deux sur le chemin des classes. Cela conduit à du code de la version 4 du pilote utilisant le code de la version 3 et un résultat NoSuchFieldError .

Vous pouvez éviter le problème en excluant le pilote Mongo de la dépendance Mongobee:

compile('com.github.mongobee:mongobee:0.13') {
    exclude group: 'org.mongodb'
}


6 commentaires

En excluant le mongoDb, j'obtiens l'erreur comme Mongobee runner = new Mongobee (mongoUri); ^ fichier de classe pour com.mongodb.MongoClient introuvable


Je dois ajouter la compilation "org.mongodb: mongo-java-driver: 3.12.6" pour que cela fonctionne. Est-ce une meilleure façon?


Maintenant, je reçois un nouveau problème. Une tentative a été faite pour appeler une méthode qui n'existe pas. La tentative a été effectuée à partir de l'emplacement suivant: org.springframework.data.mongodb.core.MongoTemplate.lambda $ i‌ nsertDocumentList $ 16‌ (MongoTemplate.java:‌ 1468) La méthode suivante n'existait pas: 'com.mongodb. client.result.InsertManyResult com.mongodb.client.MongoCollection.insertMany (java.util.List‌) '


Vous ne pouvez pas utiliser mongo-java-driver: 3.12.6 avec Spring Boot 2.3. Il nécessite la version 4 du pilote de Mongo. Si Mongobee nécessite 3.x, vous devrez soit revenir à Spring Boot 2.2, soit arrêter d'utiliser Mongobee. Je recommanderais ce dernier car Mongobee semble avoir été abandonné. Il existe un fork plus actif mais il n'a pas encore été mis à niveau vers la version 4 du pilote de Mongo .


Merci Andy ça a du sens pour moi. Merci beaucoup


@AndyWilkinson - La bibliothèque que vous mentionnez est désormais obsolète et ses créateurs recommandent d'utiliser la bibliothèque Mongock compatible avec mongobee.



0
votes

Vous rencontrez une incompatibilité entre le pilote MongoDB Java requis par les nouvelles versions de Spring Data MongoDB , et celui utilisé par mongobee . Spring Data MongoDB nécessite la version 4 des bibliothèques Mongo Java, alors que mongobee nécessite la version 3. Les deux versions sont incompatibles l'une avec l'autre et ne peuvent pas être utilisées simultanément dans une application. , le dernier engagement ayant été effectué en mars 2018 et aucune réponse aux problèmes des créateurs depuis lors. Par conséquent, ne vous attendez pas à ce qu'une version mise à jour de cette bibliothèque soit publiée avec le support de la nouvelle version des pilotes Mongo Java.

En raison de cet abandon du projet, plusieurs bibliothèques successeurs ont été dérivées de mongobee. D'après ce que j'ai pu déterminer, Mongock est la seule bibliothèque successeur activement maintenue. Il prend en charge les versions 3 et 4 des bibliothèques Java Mongo.

Mongock est une évolution significative de Mongobee, avec support intégré pour la migration depuis mongobee . En plus de sa prise en charge intégrée de la version 4 du pilote Mongo Java, il dispose d'une intégration intégrée facultative avec Spring & Spring Boot.

Par conséquent, si vous souhaitez utiliser une version récente de Spring Data MongoDB avec une bibliothèque de migration compatible mongobee, Mongock sera l'approche la plus simple et la plus directe.

dependencies {
    [...]

    compile 'com.github.cloudyrock.mongock:mongock-api:4.1.14'
}


0 commentaires