Spring Batch MongoDB 依赖问题

Posted

技术标签:

【中文标题】Spring Batch MongoDB 依赖问题【英文标题】:Spring Batch MongoDB Dependency Issue 【发布时间】:2017-03-20 05:08:29 【问题描述】:

由于以下异常,我无法让我的 Spring Batch 应用程序运行;

java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
at org.springframework.data.mapping.model.BasicPersistentEntity.findAnnotation(BasicPersistentEntity.java:371)
at org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity.<init>(BasicMongoPersistentEntity.java:80)
at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:91)
at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:39)
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:309)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:180)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:140)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:67)
at org.springframework.data.mongodb.core.MongoTemplate.getPersistentEntity(MongoTemplate.java:1992)
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:957)
at org.springframework.batch.item.data.MongoItemWriter.doWrite(MongoItemWriter.java:128)
at org.springframework.batch.item.data.MongoItemWriter$1.beforeCommit(MongoItemWriter.java:156)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:928)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:740)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy45.commit(Unknown Source)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:150)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy46.run(Unknown Source)
at com.diona.batch.personload.Application.main(Application.java:53)

我认为问题是因为在添加此方法时我应该使用 spring-core 4.2 或更高版本,尽管我无法解释 maven 依赖层次结构以查明问题。

我正在使用 Eclipse 并生成了依赖层次结构并专注于 spring-core。结果如下;

spring-core hierarcy

是什么导致我在这里使用 spring-core 4.0.7 而不是我需要使用的 4.2+?

谢谢,

比克

PS 更新以添加我的 POM;

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.diona.batch</groupId>
<artifactId>person-load-batch</artifactId>
<version>0.1.0</version>

<properties>
    <java.version>1.8</java.version>
    <spring.boot.version>1.4.1.RELEASE</spring.boot.version>
    <spring.batch.version>3.0.7.RELEASE</spring.batch.version>
    <spring.data.releasetrain>Hopper-SR4</spring.data.releasetrain>
    <oracle.driver.version>11.2.0</oracle.driver.version>
    <mongodb.driver.version>2.11.2</mongodb.driver.version>
    <junit.version>3.8.1</junit.version>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.1.6.RELEASE</version>
    <relativePath></relativePath>
</parent>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>$spring.data.releasetrain</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>

    <!-- spring boot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>  
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>        
    </dependency>       

    <!-- spring batch -->
    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-core</artifactId>
        <version>$spring.batch.version</version>
    </dependency>

    <!-- ORACLE database driver -->
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>$oracle.driver.version</version>
    </dependency>

    <!-- MongoDB database driver -->
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>$mongodb.driver.version</version>
    </dependency>

    <!-- JUnit framework -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>$junit.version</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

【问题讨论】:

你应该显示你的 pom 的内容。 更新添加pom。 【参考方案1】:

您将 Spring Boot 启动器与 Spring Data 发布火车的东西混合在一起。此外,您使用的是带有最新 Spring Data 的非常旧版本的 Spring Boot。如果你使用的是 Spring Boot,那么你的 POM 应该是这样的:

另请参阅Getting Started with Spring Data Mongo

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.diona.batch</groupId>
<artifactId>person-load-batch</artifactId>
<version>0.1.0</version>

<properties>
    <java.version>1.8</java.version>
    <spring.boot.version>1.4.1.RELEASE</spring.boot.version>
    <oracle.driver.version>11.2.0</oracle.driver.version>
    <junit.version>3.8.1</junit.version>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>$spring.boot.version</version>
</parent>

<dependencies>
    <!-- spring boot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>  
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>        
    </dependency>       
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>

    <!-- ORACLE database driver -->
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>$oracle.driver.version</version>
    </dependency>

    <!-- JUnit framework -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>$junit.version</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

【讨论】:

我需要 spring 数据来做我想做的事情 - 这基本上是从 Oracle 数据库读取并写入 mongodb。如果我将 spring boot 更新到您推荐的版本,我可以使用最新发布的 trainspring 数据发布 train 吗? @bicster,你已经加入了spring-boot-starter-data-jpa。您将拥有从 Oracle 读取的所有内容(您已包含驱动程序)。我已经更新了我的答案以包括 MongoDB 的东西。 问题是 - 为什么?我以为我必须导入与 spring 数据相关的所有内容,但我猜 spring boot 正在使用 spring-boot-starter-data-mongodb 依赖项为我做这件事?我是春天的新手,所以这还是有点混乱!

以上是关于Spring Batch MongoDB 依赖问题的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 之 Spring Batch 批处理实践

Spring Boot 之 Spring Batch 批处理实践

Spring Batch 使用带有 Spring Boot 的 MongoDB 抛出无法确定数据库类型的嵌入式数据库驱动程序类 NONE

从DB2获取数据并使用没有元数据表的Spring Batch保存在MongoDB中

无法打开spring-batch-core

应用上下文中一些bean的依赖在Spring Batch中形成了一个循环