如果一个字段被注释了
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;
}
当创建/更新引用列实体的责任不在当前实体中,而是在另一个实体中时,您可以这样做。
BalusC和Pascal Thivent的答案,insertable=false, updatable=false
的另一个常见用法:考虑一个不是
id 而是某种 序列号 的列。计算序列号的责任不一定属于应用程序。
例如,序列号从 1000 开始,每个新实体应加一。这在数据库中很容易完成,而且非常恰当,在这种情况下,这些配置是有意义的。
@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;
(这里我不讨论可更新视图)
insertable=false, updatable=false
的一个常见用途是节省冗余的数据库查询,从而提高性能。想象有一个 Client 类,它有一个 Parent 实体。如果您只想检查客户端是否有父级,则只需检查其
parent_id
列中是否存在值即可。无需要求 Hibernate 获取父实体(可能还有其所有其他关联),从而导致额外的查询数量:
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
列中的任何值,该值仅由父实体编辑/更新。