我试图运行我的第一个Batch Spring应用程序,但我在运行时遇到了行映射器的问题:
无法将[com.tutoref.batch.ProductMapper]类型的值转换为 属性的必需类型[org.springframework.jdbc.core.RowMapper] ' rowMapper':找不到匹配的编辑器或转换策略
程序必须将我的sql中的一些数据导出到平面文件(csv)。在下面我包括主文件(如果需要,我可以添加任何文件)。我也关注我的pom.xml中的版本。
我的IDE是eclipse。这是我的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
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.tutoref</groupId>
<artifactId>spring-batch-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-batch-example</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Spring core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<!-- Spring batch core -->
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>3.0.8.RELEASE</version>
</dependency>
<!-- MySQL connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!-- Spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<!-- The JAXB Api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.6</version>
</dependency>
<!-- Junit for unit testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
我的工作定义xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
">
<import resource="spring-context.xml" />
<import resource="datasource.xml" />
<bean id="product" class="com.tutoref.batch.entity.Product" scope="prototype" />
<bean id="itemProcessor" class="com.tutoref.batch.ProductItemProcessor" />
<bean id="jobListener" class="com.tutoref.batch.ProductJobListener" />
<!-- Reading from the database and returning a mapper row -->
<bean id="productItemReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="productDataSource" />
<property name="sql" value="SELECT * FROM products" />
<property name="rowMapper">
<bean class="com.tutoref.batch.ProductMapper" />
</property>
</bean>
<!-- Writing a line into an output flat file -->
<bean id="productFlatFileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<property name="resource" value="file:csv/products.csv" />
<!-- Converting a product object into delimited list of strings -->
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value="|" />
<property name="fieldExtractor">
<!-- Returning the value of beans property using reflection -->
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="name,unitPrice,quantity" />
</bean>
</property>
</bean>
</property>
</bean>
<!-- And finally ... the job definition -->
<batch:job id="productJob">
<batch:step id="step1">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="productItemReader" writer="productFlatFileItemWriter"
processor="itemProcessor" commit-interval="10" />
</batch:tasklet>
</batch:step>
<batch:listeners>
<batch:listener ref="jobListener" />
</batch:listeners>
</batch:job>
</beans>
行映射器代码:
public class ProductMapper implements FieldSetMapper<Product> {
@Override
public Product mapFieldSet(FieldSet fieldSet) throws BindException {
Product product = new Product();
product.setId(fieldSet.readInt(0));
product.setName(fieldSet.readString(1));
product.setQuantity(fieldSet.readInt(2));
product.setUnitPrice(fieldSet.readDouble(3));
return product;
}
}
主要课程:
public class App
{
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("job-products.xml");
JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
Job job = (Job) context.getBean("productJob");
try {
JobExecution execution = jobLauncher.run(job, new JobParameters());
System.out.println("Job Exit Status : "+ execution.getStatus());
} catch (JobExecutionException e) {
System.out.println("The Job has failed :" + e.getMessage());
e.printStackTrace();
}
}
}
异常的堆栈跟踪:
信息:没有设置TaskExecutor,默认为同步 遗嘱执行人。正在加载课程
com.mysql.jdbc.Driver'. This is deprecated. The new driver class is
com.mysql.cj.jdbc.Driver&#39;。司机是 通过SPI自动注册并手动加载驱动程序 上课通常是不必要的。 2017年7月30日下午2:09:59 org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName INFO:已加载的JDBC驱动程序:com.mysql.jdbc.Driver 线程&#34; main&#34;中的例外情况 org.springframework.beans.factory.BeanCreationException:错误 创建名为&#39; productItemReader&#39;的bean在类路径中定义 resource [job-products.xml]:bean的初始化失败;嵌套 例外是 org.springframework.beans.ConversionNotSupportedException:失败 转换类型&#39; com.tutoref.batch.ProductMapper&#39;的属性值至 必需的类型&#39; org.springframework.jdbc.core.RowMapper&#39;对于财产 &#39;的RowMapper&#39 ;;嵌套异常是java.lang.IllegalStateException: 无法将[com.tutoref.batch.ProductMapper]类型的值转换为 属性的必需类型[org.springframework.jdbc.core.RowMapper] &#39; rowMapper&#39;:找不到匹配的编辑器或转换策略 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 在 org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:304) 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703) 在 org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) 在 org.springframework.context.support.ClassPathXmlApplicationContext。(ClassPathXmlApplicationContext.java:139) 在 org.springframework.context.support.ClassPathXmlApplicationContext。(ClassPathXmlApplicationContext.java:83) 在com.tutoref.batch.App.main(App.java:19)引起: org.springframework.beans.ConversionNotSupportedException:失败 转换类型&#39; com.tutoref.batch.ProductMapper&#39;的属性值至 必需的类型&#39; org.springframework.jdbc.core.RowMapper&#39;对于财产 &#39;的RowMapper&#39 ;;嵌套异常是java.lang.IllegalStateException: 无法将[com.tutoref.batch.ProductMapper]类型的值转换为 属性的必需类型[org.springframework.jdbc.core.RowMapper] &#39; rowMapper&#39;:找不到匹配的编辑器或转换策略 org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:474) 在 org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:511) 在 org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:505) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1502) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1461) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ... 11更多引起:java.lang.IllegalStateException:不能 将[com.tutoref.batch.ProductMapper]类型的值转换为必需值 输入属性的[org.springframework.jdbc.core.RowMapper] &#39; rowMapper&#39;:找不到匹配的编辑器或转换策略 org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267) 在 org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:459) ......还有17个
由于
答案 0 :(得分:2)
无法将[com.tutoref.batch.ProductMapper]类型的值转换为所需类型[org.springframework.jdbc.core.RowMapper]的属性&#39; rowMapper&#39;:找不到匹配的编辑器或转换策略< / p>
此异常表示productItemReader
bean正在等待org.springframework.jdbc.core.RowMapper
属性中的rowmapper
对象,但它正在接收类型为com.tutoref.batch.ProductMapper
的引用对象。
问题出在public class ProductMapper implements FieldSetMapper<Product>
转到ProductMapper类并实现org.springframework.jdbc.core.RowMapper而不是FieldSetMapper
这是一个实现RowMapper接口,MessageContainer如何在项目中像Product
类这样的pojo示例的示例。
public class MessageContainerMapper implements RowMapper<MessageContainer> {
@Override
public MessageContainer mapRow(ResultSet rs, int rowNum) throws SQLException {
MessageContainer mc = new MessageContainer();
mc.setId(rs.getInt("id"));
mc.setName(rs.getString("name"));
return mc;
}
}