Java Spring批导入期间枚举到字符串的转换失败

Java Spring批导入期间枚举到字符串的转换失败,java,mysql,spring,hibernate,spring-batch,Java,Mysql,Spring,Hibernate,Spring Batch,我正在使用Spring Boot和Hiberna创建Spring批处理作业,但在插入过程中遇到问题。这是守则的相关部分: @Bean public JdbcBatchItemWriter<OphthalmicLens> writer(DataSource dataSource) throws SQLException { return new JdbcBatchItemWriterBuilder<OphthalmicLens>()

我正在使用Spring Boot和Hiberna创建Spring批处理作业,但在插入过程中遇到问题。这是守则的相关部分:

@Bean
    public JdbcBatchItemWriter<OphthalmicLens> writer(DataSource dataSource) throws SQLException {
        return new JdbcBatchItemWriterBuilder<OphthalmicLens>()
                .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
                .sql("INSERT INTO OphthalmicLens (`createdBy`,`createdDate`,`lastModifiedBy`,`lastModifiedDate`,`sid`,`version`,`manufacturer`,`manufacturerCode`,`name`,`sku`,`upc`,`cylinder`,`design`,`diameter`,`index`,`material`,`source`,`sphere`,`type`) VALUES (:createdBy,NOW(),:lastModifiedBy,NOW(),UUID(),:version,:manufacturer,:manufacturerCode,:name,:sku,:upc,:cylinder,:design,:diameter,:index,:material,:source,:sphere,:type)")
                .dataSource(dataSource).build();
    }
在my
Ophthaliclens
bean中使用,如下所示:

@NotNull
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private OphthalmicDesign design = OphthalmicDesign.SPHERIC;
我使用的是Mysql 5.7,数据库中的列是mappes,正如预期的那样,它是VARCHAR(255)

当我运行作业时,出现以下错误:

Caused by: java.sql.BatchUpdateException: Incorrect string value: '\xAC\xED\x00\x05~r...' for column 'design' at row 1
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_172]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_172]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_172]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_172]
    at com.mysql.cj.util.Util.handleNewInstance(Util.java:210) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.util.Util.getInstance(Util.java:185) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.util.Util.getInstance(Util.java:192) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.jdbc.exceptions.SQLError.createBatchUpdateException(SQLError.java:218) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchedInserts(ClientPreparedStatement.java:768) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchInternal(ClientPreparedStatement.java:444) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.jdbc.StatementImpl.executeBatch(StatementImpl.java:839) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.zaxxer.hikari.pool.ProxyStatement.executeBatch(ProxyStatement.java:128) ~[HikariCP-2.7.9.jar:?]
我知道问题在于枚举没有转换为字符串。我可以使用不同的
BeanPropertyItemSqlParameterSourceProvider来解决这个问题,但我认为这样做太过繁琐,而且会失去Spring工具的优势


您是否有提示,告诉Spring/Hibernate即使在我使用Spring Batch时也自动将该枚举转换为字符串?

您可以指示
BeanPropertyItemSqlParameterSourceProvider
返回
VARCHAR
字段
design
的类型,如下所示:

@Bean
public JdbcBatchItemWriter<OphthalmicLens> writer(DataSource dataSource) throws SQLException {
    return new JdbcBatchItemWriterBuilder<OphthalmicLens>()
            .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<OphthalmicLens>() {
                @Override
                public SqlParameterSource createSqlParameterSource(OphthalmicLens item) {
                    return new BeanPropertySqlParameterSource(item) {
                        @Override
                        public int getSqlType(String paramName) {
                            if (paramName.equalsIgnoreCase("desing")) {
                                return Types.VARCHAR;
                            }
                            return super.getSqlType(paramName);
                        }
                    };
                }
            })
            .sql("INSERT INTO OphthalmicLens (`createdBy`,`createdDate`,`lastModifiedBy`,`lastModifiedDate`,`sid`,`version`,`manufacturer`,`manufacturerCode`,`name`,`sku`,`upc`,`cylinder`,`design`,`diameter`,`index`,`material`,`source`,`sphere`,`type`) VALUES (:createdBy,NOW(),:lastModifiedBy,NOW(),UUID(),:version,:manufacturer,:manufacturerCode,:name,:sku,:upc,:cylinder,:design,:diameter,:index,:material,:source,:sphere,:type)")
            .dataSource(dataSource)
            .build();
}
@Bean
公共JdbcBatchItemWriter编写器(DataSource DataSource)引发SQLException{
返回新的JdbcBatchItemWriterBuilder()
.itemSqlParameterSourceProvider(新的BeanPropertyItemSqlParameterSourceProvider(){
@凌驾
公共SqlParameterSource createSqlParameterSource(眼科项目){
返回新的BeanPropertySqlParameterSource(项){
@凌驾
public int getSqlType(字符串参数名){
if(paramName.equalsIgnoreCase(“设计”)){
返回类型.VARCHAR;
}
返回super.getSqlType(paramName);
}
};
}
})
.sql(“插入到眼科(`createdBy`、`createdDate`、`lastModifiedBy`、`lastModifiedDate`、`sid`、`version`、`manufacturerCode`、`name`、`sku`、`upc`、`cylinder`、`design`、`diameter`、`index`、`material`、`source`、`sphere`、`type`)值(:createdBy、NOW()、lastModifiedBy、NOW()、UUID(),:版本,:制造商,:制造商代码,:名称,:sku,:upc,:圆柱体,:设计,:直径,:索引,:材料,:来源,:球体,:类型)“)
.dataSource(数据源)
.build();
}

您正在使用Hibernate来管理实体,但使用
JdbcBatchItemWriter
来编写实体。是否有什么东西阻止您使用
HibernateItemWriter
?本文作者知道如何在保存项时根据您的映射将字段映射到正确的类型。如果将该列“design”作为VARCHAR,然后使用另一个get方法将ENUM返回到外部,该怎么办。“design”列仅用于数据映射。不要直接使用该列。他们将使用“get”方法返回ENUM@MahmoudBenHassine出于性能原因,我需要执行本机查询。通常在我的查询中,我会在更新()时插入()VALUES()@NghiaDo,我给了我一个好主意。我对它做了一些修改:我创建了一个getDesignString()并使用了该字段。也许这不是解决它的最优雅的方法。通常我所做的是,实体将直接映射到数据库模式,然后我从实体映射到模型Pojo并返回到业务层。在这种情况下,作为VARCHAR的“设计”将在DB实体中,作为ENUM的“设计”将在模型Pojo中
@Bean
public JdbcBatchItemWriter<OphthalmicLens> writer(DataSource dataSource) throws SQLException {
    return new JdbcBatchItemWriterBuilder<OphthalmicLens>()
            .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<OphthalmicLens>() {
                @Override
                public SqlParameterSource createSqlParameterSource(OphthalmicLens item) {
                    return new BeanPropertySqlParameterSource(item) {
                        @Override
                        public int getSqlType(String paramName) {
                            if (paramName.equalsIgnoreCase("desing")) {
                                return Types.VARCHAR;
                            }
                            return super.getSqlType(paramName);
                        }
                    };
                }
            })
            .sql("INSERT INTO OphthalmicLens (`createdBy`,`createdDate`,`lastModifiedBy`,`lastModifiedDate`,`sid`,`version`,`manufacturer`,`manufacturerCode`,`name`,`sku`,`upc`,`cylinder`,`design`,`diameter`,`index`,`material`,`source`,`sphere`,`type`) VALUES (:createdBy,NOW(),:lastModifiedBy,NOW(),UUID(),:version,:manufacturer,:manufacturerCode,:name,:sku,:upc,:cylinder,:design,:diameter,:index,:material,:source,:sphere,:type)")
            .dataSource(dataSource)
            .build();
}