如果某个字段已注释insertable=false, updatable=false
,这是否意味着您不能插入值也不能更改现有值?你为什么要那样做?
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(mappedBy="person", cascade=CascadeType.ALL)
private List<Address> addresses;
}
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
@JoinColumn(name="ADDRESS_FK")
@Column(insertable=false, updatable=false)
private Person person;
}
答案 0 :(得分:103)
当创建/更新相关实体的责任不在当前实体中时,您会这样做。例如。您有Person
和Address
。您希望insertable=false, updatable=false
与@OneToMany
实体中Person
实体的Address
关系添加Address
,因为它不是Person
实体的责任创建或更新{{1}}。反之亦然。
答案 1 :(得分:88)
当您需要在实体中多次映射字段时,定义insertable=false, updatable=false
非常有用,通常是:
这是IMO不是一个语义的东西,但绝对是技术性的。
答案 2 :(得分:19)
我想补充 BalusC 和 Pascal Thivent 的答案insertable=false, updatable=false
的另一个常见用途:
考虑一个不是 id 的列,但是某种序列号。计算序列号的责任可能不一定属于申请。
例如,序列号从1000开始,每个新实体应增加1。这在数据库中很容易完成,非常恰当,在这种情况下,这些配置是有意义的。
答案 3 :(得分:7)
另一个示例是在“created_on”列中,您希望让数据库处理日期创建
答案 4 :(得分:0)
答案 5 :(得分:0)
另一个原因可能是您的属性映射到视图的列(例如,您的休眠实体是表和视图的融合)。因此,您的列可以插入(或更新)是没有意义的。
@Entity
@Table(name = "THE_VIEW")
@SecondaryTable(name = "THE_TABLE", pkJoinColumns = @PrimaryKeyJoinColumn(name = "THE_ID"))
public class MyEntity {
@Id
@Column(name = "THE_ID")
private Integer id;
@Column(name = "VIEW_COLUMN", updatable = false, insertable = false)
private String viewColumn
@Column(name = "TABLE_COLUMN", table = "THE_TABLE")
private String tableColumn;
(这里不讨论可更新的视图)
答案 6 :(得分:0)
补充之前的答案,insertable=false, updatable=false
的一个常见用途是节省冗余的数据库查询,从而提高性能。
想象有一个 Client 类,它有一个 Parent 实体。如果您只想检查 Client 是否有 Parent,您只需检查其 parent_id
列中是否存在值。没有必要要求 Hibernate 获取 Parent 实体,可能还有它的所有其他关联,从而导致额外数量的查询:
public class Client {
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST}, fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Parent parent;
@Column(name = "parent_id", insertable = false, updatable = false)
private UUID parentId;
}
通过上述设置,parentId
字段将简单地获取存储在 parent_id
列中的任何值,该列仅由父实体编辑/更新。
答案 7 :(得分:0)