- 此问题在此处已有答案**:
(18个答案)
9天前关闭。
我正在使用hbm2java(它是Hibernate Tools的一部分)将数据库反向工程为JPA实体类。
我通过./mvnw clean generate-sources
运行该工具,生成实体类并保存到target/generated-sources
。
在UserAccount
数据库表中,Created
列的定义如下。请注意默认值:
Created TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
当hbm2java对该列进行反向工程时,不包括缺省值:
...
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "CREATED", nullable = false, length = 29)
public Timestamp getCreated() {
return this.created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
...
因此,在尝试将UserAccount
实体保存到数据库时会引发DataIntegrityViolationException
:
数据完整性违规异常:非空属性引用空值或 transient 值:com.example.UserAccount.created
真的希望有一种方法可以解决这个问题,因为我有相当多的数据库列有默认值,最复杂的是:
DEFAULT 'User' + CAST(NEXT VALUE FOR SeqUserAccountUsername as VARCHAR(19))
...只生成字符串,如User13。
我还在学习SpringBoot和Hibernate,可能需要一些关于解决这个问题的最佳方法的建议。
我目前的研究:
- same question早在2007年就在Hibernate论坛上被要求使用,但没有提供解决方案。
- This documentation谈到使用"default-value"属性来设置"字段的默认初始化值",这是正确的方法吗?
2条答案
按热度按时间tvokkenx1#
我 * 相信 * 下面的Map应该可以在所有最近的Hibernate版本中工作:
如果不管用,告诉我。
(It当然,逆向工程工具对默认值一无所知。)
b0zn9rqh2#
首先,你需要找一个能够解释数据库工作原理的人。问题是像
TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
这样的SQL列定义意味着:DEFAULT
,在这种情况下DB根据默认表达式生成值(在您的情况下为CURRENT_TIMESTAMP
)要在
Hibernate
中获得完全相同的功能/能力,最简单的方法是使用JPA Callbacks,smth。例如:它允许你指定任意创建的时间戳,并且只有当它是
null
Hibernate
时才会使用当前时间--这正是DB允许你做的。其他选项做类似的事情,但不一样,但其中一些可能适合你。
@CreationTimestamp
:它忽略
this.created
的值,并将Java端计算的当前时间插入DB。@Generated(GenerationTime.INSERT)
它忽略了
this.created
的值,并将值的生成委托给DB,基本上它省略了INSERT语句中的相应列(嗯......"generate"在这里不是正确的定义)。如果您选择使用
@CreationTimestamp
或@Generated(GenerationTime.INSERT)
,请删除相应settervoid setCreated(Timestamp created)
,以避免混淆created
字段的可变性。