Java 请参考JPA@Column注释解释insertable=false和updateable=false
如果一个字段被注释为Java 请参考JPA@Column注释解释insertable=false和updateable=false,java,jpa,jakarta-ee,eclipselink,Java,Jpa,Jakarta Ee,Eclipselink,如果一个字段被注释为insertable=false,updateable=false,这不意味着您不能插入值或更改现有值吗?你为什么要这么做 @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @OneToMany(mappedBy="person", cascade=CascadeType.ALL) pr
insertable=false,updateable=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;
}
@实体
公共阶层人士{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@OneToMany(mappedBy=“person”,cascade=CascadeType.ALL)
私人名单地址;
}
@实体
公共课堂演讲{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@许多酮
@JoinColumn(name=“ADDRESS\u FK”)
@列(可插入=false,可更新=false)
私人;
}
当创建/更新引用列的职责不在当前实体中,而是在另一个实体中时,您可以这样做。当您需要在实体中多次映射字段时,定义insertable=false,updateable=false
非常有用,通常:
- 使用复合键时
- 当使用
- 使用时
这不是一个语义问题,但绝对是一个技术问题。我想在BalusC和Pascal Thivent的答案中添加
insertable=false,updateable=false的另一个常见用法:
考虑一个不是id而是某种序列号的列。计算序列号的责任不一定属于应用程序
例如,序列号从1000开始,每增加一个新实体,序列号应增加一个。这在数据库中很容易做到,而且非常合适,在这种情况下,这些配置是有意义的。另一个例子是在“created_on”列中,您希望让数据库根据Javax的持久性文档处理日期创建:
该列是否包含在持久性提供程序生成的SQL UPDATE语句中
最好从官方文档中理解。另一个原因可能是您的属性是视图列的映射器(例如,hibernate实体是表和视图的融合)。因此,可以插入(或更新)您的列是没有意义的
(我这里不谈可更新视图)除了前面的答案之外,insertable=false,updateable=false
的一个常见用法是保存冗余的数据库查询,从而提高性能
想象一下有一个客户机类,它有一个父实体。如果只想检查客户机是否有父级,只需检查其Parent\u 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\u id
列中的任何值,该列由父实体单独编辑/更新。我坚信这个答案比公认的答案要好得多。接受的答案传达了一种感觉,即可插入/可更新属性与相关实体的创建/更新有关,而这些属性背后的真正意图是防止在当前实体中插入/更新列。相关实体的创建/更新由映射注释的cascade属性处理。序列也受JPA支持,因此您也可以使用JPA注释定义序列。您的意思是,如果updateable=false on Person,则在更新地址时将禁用Person.name的更新(我不同意,因为这是级联的目的)。你还说@Column定义在外键(Person)和非外键(因为没有引用实体来禁用更新)时做了一些不同的事情。通过阅读javadoc for Updateable,我想说,如果某个地址一旦被持久化,它只会禁用为给定地址更改Person。您能解释一下吗?级联选项是否已经充分定义了这一点?我看到它被用来避免在尝试写入生成的列时遇到麻烦。(例如,始终生成为(高度*宽度*长度)虚拟的卷列)Hibernate是否应该阻止基于Updateable=false注释的更新?在我的JPA存储库测试中,使用此注释创建的列毫无怨言地接受更新。@ChrisinTown Eclipselink将根本不在sql中包含该列。我希望Hibernate的情况与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;
}