Spring Boot 2+Hibernate 5中@Embeddable属性在H2(create-drop)生成错误字段长度
解决Spring Boot 2.0.1中@Embeddable类字段长度生成错误的问题
我之前也碰到过这个情况,在Spring Boot 2.0.x搭配默认Hibernate(5.2.x版本)和H2数据库时,@Embeddable类里的@Size注解经常不会被Hibernate自动转化为数据库列的长度约束,导致生成的字段长度不符合预期。下面是具体的原因分析和解决方案:
问题原因
Hibernate 5.2默认没有开启将JSR-380 Bean Validation注解(比如@Size)映射到数据库DDL的功能,而且这个配置在Spring Boot 2.0.1中也没有默认启用。另外,嵌入式类(@Embeddable)的注解识别优先级可能比实体类低,进一步导致字段长度不生效。
解决方案
方案1:开启Hibernate的Validation到DDL映射
在你的application.properties或application.yml中添加以下配置,让Hibernate自动将@Size等注解转化为数据库列的长度约束:
application.properties写法:
spring.jpa.hibernate.ddl-auto=update # 确保DDL自动生成功能开启,create/create-drop也可以 spring.jpa.properties.hibernate.validator.apply_to_ddl=true
application.yml写法:
spring: jpa: hibernate: ddl-auto: update properties: hibernate: validator: apply_to_ddl: true
方案2:显式使用@Column指定字段长度
如果方案1不生效,或者你想更精准地控制数据库列属性,可以直接在@Embeddable类的字段上添加JPA的@Column注解,显式指定长度。这种方法不受Hibernate配置影响,更可靠:
修改后的Address类示例:
@Embeddable public class Address { @NotBlank @Size(min=3, max=100) @Column(length = 100) // 显式指定列长度为100 private String street; @NotBlank // 假设你还有city字段,同样可以添加@Column @Size(min=2, max=50) @Column(length = 50) private String city; // 其他字段、构造方法和getter/setter... }
Publisher类保持原有代码即可:
@Entity public class Publisher { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; @NotBlank @Size(min=2, max=150) private String name; @NotNull private Address address; // 其他字段、构造方法和getter/setter... }
验证方法
配置完成后,启动应用,访问H2控制台(默认地址:http://localhost:8080/h2-console),连接到你的数据库,查看publisher表的结构,确认street、city等字段的长度是否符合你设置的值。
内容的提问来源于stack exchange,提问作者Kaz
相关产品推荐
相关产品推荐

