Java 冬眠';s ddl auto=验证和列默认值
如何让Hibernate在启动时验证列默认值(通过Java 冬眠';s ddl auto=验证和列默认值,java,hibernate,Java,Hibernate,如何让Hibernate在启动时验证列默认值(通过Hibernate.hbm2ddl.auto=validate) 更新 从我的分析中,我只看到Hibernate在评估列的类型,仅此而已。请参阅:org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable() 如果我想验证诸如默认值之类的信息,我可能必须编写自己的代码,遍历Hibernate实体的元模型和数据库表 主要问题: 当Hibernate实体中的
Hibernate.hbm2ddl.auto=validate
)
更新
- 从我的分析中,我只看到Hibernate在评估列的类型,仅此而已。请参阅:
org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable()
- 如果我想验证诸如默认值之类的信息,我可能必须编写自己的代码,遍历Hibernate实体的元模型和数据库表
主要问题:
- 当Hibernate实体中的默认值定义与实际数据库的默认值设置不匹配时,Hibernate不会在启动期间抛出错误。我希望看到一个错误。我如何确保它被抛出
- 当列的数据类型不匹配时,Hibernate会在启动时抛出一个错误(这是一件好事)
详细信息:MariaDB命令行 我通过以下方式创建了一个MariaDB表:
CREATE TABLE `person2` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`age` int(11) DEFAULT 27,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
当我使用mysql命令行并手动运行insert语句时,新记录的age
设置为27(预期行为):
我还可以显式提供年龄,并且它接受提供的值(预期行为):
详细信息:休眠 我正在使用Spring/Hibernate,我创建了以下类来映射到
person2
表:
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.Type;
import javax.persistence.*;
@Entity
@Table(name = "person2")
@DynamicInsert
public class Person2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Type(type = "text")
@Column(nullable = false)
private String name;
@ColumnDefault("27")
@Column
private Integer age;
// Normal getters/setters:
public void setName(String val) {
this.name = val;
}
public String getName() {
return this.name;
}
public void setAge(Integer val) {
this.age = val;
}
public Integer getAge() {
return this.age;
}
}
为了在Spring启动时生成一些测试数据,我有以下几点:
@Configuration
public class DatabaseLoader {
@Order(1)
@Bean
public CommandLineRunner createTestData(Person2Repository person2Repository) {
Person2 person2 = new Person2();
person2.setName("hibernate: Bob 10");
person2Repository.save(person2);
...
return args -> {
};
}
}
乍一看,一切都很好:一行被添加到数据库中,右边的名称和年龄=27
休眠阴性测试:
我想确保Hibernate的Hibernate.hbm2ddl.auto=validate
工作正常。因此,我做了以下工作:
@Configuration
public class DatabaseLoader {
@Order(1)
@Bean
public CommandLineRunner createTestData(Person2Repository person2Repository) {
Person2 person2 = new Person2();
person2.setName("hibernate: Bob 10");
person2Repository.save(person2);
...
return args -> {
};
}
}
我在entity类中将age的类型从Integer更改为Long:
@Entity
@Table(name = "person2")
@DynamicInsert
public class Person2 {
...
@ColumnDefault("27")
@Column
private Long age;
}
正如预期的那样,Hibernate引发了以下错误:
- 原因:javax.persistence.PersistenceException:[PersistenceUnit:default]无法构建Hibernate SessionFactory;嵌套异常为org.hibernate.tool.schema.spi.SchemaManagementException:模式验证:表[person2]中的[age]列中遇到错误的列类型;找到[int(类型#整型)],但应为[bigint(类型#整型)]
酷,我想抛出那个错误。然后我想测试另一个场景:导致列默认值设置不匹配。但是,当我进行如下所示的修改时,启动时没有出现错误(这不是我所期望的):
Hibernate在输入错误时甚至没有抛出错误,但输入了一个虚假的默认值(非数字):
所以我想让我们试试设置默认值的columnDefinition
技术。同样,我使用了一个伪值(见下文),Hibernate没有抛出错误(这不是我所期望的):
我做错了什么?首先,您应该知道默认值是如何在数据库列中使用的<代码>默认值
在将记录保存到列中时,如果列中没有值,则会在该列中设置值,这意味着如果您正在保存记录,并且某些属性或列没有值,并且您已配置默认值,则在这种情况下,默认值会设置为该列,否则会在保存记录的时间
假设您有column1,默认值为10,那么在将记录写入表时
如果column1不为空,则写入column1的值,否则写入默认值10
更改为创建
或更新
,然后查看将发生什么。
@Entity
@Table(name = "person2")
@DynamicInsert
public class Person2 {
...
@ColumnDefault("27")
@Column
private Long age;
}
public class Person2 {
...
@ColumnDefault("999")
@Column
private Integer age;
}
public class Person2 {
...
@ColumnDefault("asdf")
@Column
private Integer age;
}
public class Person2 {
...
@Column(columnDefinition = "asdf")
private Integer age;
}