请参考JPA @Column注释解释insertable=false和updatable=false

问题描述 投票:0回答:8

如果一个字段被注释了

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;
}
java jpa jakarta-ee eclipselink
8个回答
162
投票

当创建/更新引用列实体的责任不在当前实体中,而是在另一个实体中时,您可以这样做。


150
投票
当您需要在实体中多次映射字段时,定义

insertable=false, updatable=false

 非常有用,通常是:

    使用复合键时
  • 使用
  • 共享主键时
  • 使用
  • 级联主键时
在我看来,这不是语义上的事情,但绝对是技术上的事情。


33
投票
我想添加

BalusCPascal Thivent的答案,insertable=false, updatable=false

的另一个常见用法:

考虑一个不是

id 而是某种 序列号 的列。计算序列号的责任不一定属于应用程序。

例如,序列号从 1000 开始,每个新实体应加一。这在数据库中很容易完成,而且非常恰当,在这种情况下,这些配置是有意义的。


24
投票
另一个示例是“created_on”列,您想让数据库处理日期创建


6
投票
我认为这只是意味着:

boolean insertable

(可选)该列是否包含在持久性提供程序生成的 SQL INSERT 语句中。

boolean updatable

(可选)该列是否包含在持久性提供程序生成的 SQL UPDATE 语句中。

参考:

https://www.objectdb.com/api/java/jpa/Column


2
投票
根据Javax的持久化文档:

该列是否包含在持久性提供程序生成的 SQL UPDATE 语句中。

最好从官方文档

这里来理解。


2
投票
另一个原因可能是您的属性映射到视图的列(例如,您的休眠实体是表和视图的融合)。因此,您的列可以插入(或更新)是没有意义的。

@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;
(这里我不讨论可更新视图)


2
投票
添加到前面的答案中,

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
列中的任何值,该值仅由父实体编辑/更新。

© www.soinside.com 2019 - 2024. All rights reserved.