Java Hibernate架构验证失败,MySQL字符映射到字符串
当使用Hibernate验证器验证JPA实体是否与数据库架构匹配时(通常设置为Java Hibernate架构验证失败,MySQL字符映射到字符串,java,mysql,hibernate,jpa,Java,Mysql,Hibernate,Jpa,当使用Hibernate验证器验证JPA实体是否与数据库架构匹配时(通常设置为Hibernate.ddl-auto=verify),当遇到映射到字符串字段的MySQLCHAR时,它将失败 例如,此MySQL表架构: CREATE TABLE `item` ( `id` bigint(20) NOT NULL, `name` char(50) DEFAULT NULL, PRIMARY KEY (`id`) ); 可以映射到JPA实体,如下所示: @Entity public cla
Hibernate.ddl-auto=verify
),当遇到映射到字符串
字段的MySQLCHAR
时,它将失败
例如,此MySQL表架构:
CREATE TABLE `item` (
`id` bigint(20) NOT NULL,
`name` char(50) DEFAULT NULL,
PRIMARY KEY (`id`)
);
可以映射到JPA实体,如下所示:
@Entity
public class Item
{
@Id
private Long id;
@Column
private String name;
}
验证过程将失败,例外情况如下:
org.hibernate.tool.schema.spi.SchemaManagementException:
架构验证:中的列[name]中遇到错误的列类型
表[项目];找到[char(类型#char)],但应为[varchar(255)
(类型#VARCHAR)]
一个典型的解决方案是在字段上使用Hibernate@Type
注释来指定列数据类型,这足以满足验证器的要求:
@Column
@Type(type = "char")
private String name;
当您实际发出需要将ResultSet映射到实体的查询时,您将遇到一组不同的异常(在本例中,Spring数据用于发出查询):
org.springframework.orm.jpa.JpaSystemException:无法设置字段
值[B]反射值:[class com.example.Item.name]setter
com.example.Item.name的名称;嵌套异常是
org.hibernate.PropertyAccessException:无法设置字段值[B]
反射值:[class com.example.Item.name]的setter
com.example.Item.name
及
java.lang.IllegalArgumentException:无法将java.lang.String字段com.example.Item.name设置为java.lang.Character
这些异常的解决方案是在实际的JPA
@列
注释中设置列定义,而不是特定于Hibernate的@类型
注释:
@Column(columnDefinition = "char")
private String name;
这将满足Hibernate验证器的要求,而不会让Hibernate误认为您实际上是在映射字符字段。不要在MySQL中使用
char
type。。。大多数情况下,它都映射到varchar
,但会混淆JPA/Hibernate等工具……此外,char(50)字符集utf8mb4
的一列每行使用200字节,因为“utf8mb4”每字符最多占用4字节。。。请参阅:@UsagiMiyamoto这在理想世界中非常好,但有时您使用的是无法控制使用char
的遗留模式,因此您需要妥协。