休眠模式验证失败,其中MySQL CHAR映射到String

Rob*_*unt 3 java mysql hibernate jpa

当使用Hibernate验证程序来验证JPA实体与数据库模式匹配时(通常是setting hibernate.ddl-auto = verify),当它遇到CHAR已映射到String字段的MySQL时,它将失败。

例如,以下MySQL表模式:

CREATE TABLE `item` (
  `id` bigint(20) NOT NULL,
  `name` char(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
Run Code Online (Sandbox Code Playgroud)

可以这样映射到JPA实体:

@Entity
public class Item
{
    @Id
    private Long id;

    @Column
    private String name;
}
Run Code Online (Sandbox Code Playgroud)

验证过程将失败,但以下情况除外:

org.hibernate.tool.schema.spi.SchemaManagementException: 模式验证:表[item]的列[name]中遇到的列类型错误;找到[char(Types#CHAR)],但期望[varchar(255)(Types#VARCHAR)]

一个典型的解决方案是@Type在字段上使用Hibernate 批注指定列数据类型,这足以满足验证程序的要求:

@Column
@Type(type = "char")
private String name;
Run Code Online (Sandbox Code Playgroud)

当您实际发出需要将ResultSet映射到实体的查询时,会遇到另一组异常(在这种情况下,使用Spring Data发出查询):

org.springframework.orm.jpa.JpaSystemException:无法通过反射设置字段值[B]值:[class com.example.Item.name] setter of com.example.Item.name; 嵌套异常是org.hibernate.PropertyAccessException:无法通过反射设置字段值[B]值:com.example.Item.name的[class com.example.Item.name]设置程序

java.lang.IllegalArgumentException:无法将java.lang.String字段com.example.Item.name设置为java.lang.Character

Rob*_*unt 8

这些异常的解决方案是在实际的JPA @Column批注而不是Hibernate特定的@Type批注中设置列定义:

@Column(columnDefinition = "char")
private String name;
Run Code Online (Sandbox Code Playgroud)

这将使Hibernate验证程序满意,而不会混淆Hibernate以为您实际上是在映射Character字段。