假设我们有一个包含子实体的实体。
在实体上使用insertable = false, updatable = false 可防止实体创建新的子实体并位于默认 DBMS 值之前。但是这样做的问题是我们必须始终使用默认值,或者如果我们需要实体包含另一个不是默认值的子实体,我们必须尝试在运行时将这些注释更改为insertable = true, updatable = true,所以它似乎不是一条好路。
如果在所有列中使用insertable = false, updatable = false 更有意义,则在子实体内部,这样无论我们使用哪种方法都不会创建更多子实体(@DynamicInsert 没有必要)
可以通过多种方式插入默认值,例如默认实体属性值使用构造函数或设置器。其他方法(例如将 JPA 与 columnDefinition 一起使用)的缺点是它们默认插入 null,并且 DBMS 的默认值不在前面。
使用 DBMS 插入默认值,可选使用 Hibernate
但是使用@DynamicInsert,当我们想要插入具有默认值的子实体时,我们避免向数据库发送空值,而反过来我们允许插入具有非默认值的子实体。
对于插入,该实体是否应该使用动态 sql 生成,在准备好的 sql 语句中只引用非空列?
鉴于以下需求:
- 实体不负责创建新的子实体。
- 插入实体时,子实体是在 DBMS 中定义为默认值的实体。
- 可以使用具有非默认 UUID 的子实体创建实体。
DBMS:PostgreSQL | 语言:科特林
@Entity
@Table(name = "entity")
@DynamicInsert
data class EntityTest(
@Id @GeneratedValue @Column(name = "entity_uuid") val entityUUID: UUID? = null,
@OneToOne(cascade = [CascadeType.ALL])
@JoinColumn(name = "subentity_uuid", referencedColumnName = "subentity_uuid")
var subentityTest: SubentityTest? = null
) {}
@Entity
@Table(name = "subentity")
data class SubentityTest(
@Id @GeneratedValue @Column(name = "subentity_uuid", insertable = false, updatable = false) var subentityUUID: UUID? = null,
@Column(insertable = false, updatable = false) var name: String,
) {
constructor() : this(name = "")
}
并且该值是在数据库中默认设置的:
alter table entity alter column subentity_uuid set default 'd87ee95b-06f1-52ab-83ed-5d882ae400e6'::uuid;
GL