【问题标题】:spring batch : typeMismatch.java.sql.Date,typeMismatch春季批处理:typeMismatch.java.sql.Date,typeMismatch
【发布时间】:2021-06-24 19:31:12
【问题描述】:

我正在尝试使用 Spring Batch 将此 csv 文件发送到数据库

users.csv

2021-06-22,test1@gmail.com, testFullname1, testMatricule1, 1234, testUsername1

2021-06-22,test2@gmail.com, testFullname2, testMatricule2, 0000, testUsername2

我有这个错误 无法将“java.lang.String”类型的属性值转换为属性所需的“java.sql.Date”类型

这里是批处理配置

package sofrecom.collaborateur.config;

import javax.sql.DataSource;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import sofrecom.collaborateur.model.DAOUser;



@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    public DataSource dataSource;

    @Bean
    public FlatFileItemReader<DAOUser> reader() {
        FlatFileItemReader<DAOUser> reader = new FlatFileItemReader<DAOUser>();
        reader.setResource(new ClassPathResource("users.csv"));
        reader.setLineMapper(new DefaultLineMapper<DAOUser>() {{
            setLineTokenizer(new DelimitedLineTokenizer() {{
                setNames(new String[] { "dateIntegration","email","fullname","matricule","password","username" });
            }});
            setFieldSetMapper(new BeanWrapperFieldSetMapper<DAOUser>() {{
                setTargetType(DAOUser.class);
            }});
        }});
        return reader;
    }

    @Bean
    public UserItemProcessor processor() {
        return new UserItemProcessor();
    }

    @Bean
    public JdbcBatchItemWriter<DAOUser> writer() {
        JdbcBatchItemWriter<DAOUser> writer = new JdbcBatchItemWriter<DAOUser>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<DAOUser>());
        writer.setSql("INSERT INTO user ( date_integration,email,fullname,matricule,password,username) VALUES ( :dateIntegration,:email,:fullname,:matricule,:password,:username)");
        writer.setDataSource(dataSource);
        return writer;
    }

    @Bean
    public Job importUserJob(JobCompletionNotificationListener listener) {
        return jobBuilderFactory.get("importUserJob")
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .flow(step1())
                .end()
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<DAOUser, DAOUser> chunk(10)
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .build();
    }
}

这是用户物品处理器

package sofrecom.collaborateur.config;

import java.sql.Date;
import java.text.SimpleDateFormat;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;

import sofrecom.collaborateur.model.DAOUser;


public class UserItemProcessor implements ItemProcessor<DAOUser, DAOUser> {
    private static final Logger log = LoggerFactory.getLogger(UserItemProcessor.class);
    @Autowired
    private PasswordEncoder bcryptEncoder;

    @Override
    public DAOUser process(final DAOUser person) throws Exception {

        final String password = bcryptEncoder.encode(person.getUsername());
        
        final DAOUser transformedPerson = new DAOUser(person.getDateIntegration(),person.getEmail(),person.getFullname(),person.getMatricule(),password,person.getUsername());

        log.info("Converting (" + person + ") into (" + transformedPerson + ")");

        return transformedPerson;
    }

}

请提供任何解决方案!

【问题讨论】:

  • 不,它没有用
  • 什么不起作用?您的域模型类中似乎有一个java.sql.Date 类型的字段,默认情况下不支持此类型,需要自定义转换器。请使用您尝试过但无效的更改来更新问题,或提供重现问题的minimal complete example 以便能够以有效的方式帮助您。
  • 我没有找到任何可以尝试的东西,这就是我要问的,我想要一个解决方案来尝试它,如果你能帮助我如何使用自定义转换器,谢谢。
  • 好的没问题,我会用例子补充答案。

标签: spring spring-batch


【解决方案1】:

问题在于BeanWrapperFieldSetMapper 默认情况下不知道如何在您的域对象@987654326 中将类似2021-06-22 的字符串转换为java.sql.Date 类型的对象(即字段dateIntegration) @。告诉这个映射器如何处理自定义转换的方法是注册一个ConversionService。这个转换服务应该有一个从Stringjava.sql.Date 的转换器。这是一个简单的例子:

@Bean
public FlatFileItemReader<DAOUser> reader() {
    DefaultConversionService conversionService = new DefaultConversionService();
    conversionService.addConverter(new Converter<String, Date>() { // java.sql.Date
        @Override
        public Date convert(String s) {
            return Date.valueOf(s);
        }
    });
    BeanWrapperFieldSetMapper<DAOUser> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
    fieldSetMapper.setConversionService(conversionService);
    fieldSetMapper.setTargetType(DAOUser.class);

    FlatFileItemReader<DAOUser> reader = new FlatFileItemReader<>();
    reader.setResource(new ClassPathResource("users.csv"));
    reader.setLineMapper(new DefaultLineMapper<DAOUser>() {{
        setLineTokenizer(new DelimitedLineTokenizer() {{
            setNames(new String[] { "dateIntegration","email","fullname","matricule","password","username" });
        }});
        setFieldSetMapper(fieldSetMapper);
    }});
    return reader;
}

您可以根据您在this repository 中分享的内容找到一个完整的示例。

【讨论】:

  • 是的,它现在可以工作了,非常感谢,但如果你能帮助我,仍然需要其他 2 个解决方案,第一个是我想用 PasswordEncoder 将密码从 csv 编码到 db,比如“1234 到'$2a$10$5jGCrJUVoAIkXMRFCFBv.uumpQDPsPzJK756ZHasn16p25j.cutRK' ",第二个是如何将整数 id 从 csv 转换为特定类,如“用户有一个 id_function 1 (manager),但这个 id_function 类型是 Function,它是 dao 类,如 daouser " ,非常感谢您的帮助
猜你喜欢
  • 2014-12-15
  • 2018-05-27
  • 2015-05-13
  • 2017-06-25
  • 2017-10-06
  • 2021-06-21
  • 1970-01-01
  • 2019-05-15
  • 1970-01-01
相关资源
最近更新 更多