Hibernate @OneToOne with updatable = false仍然在更新

时间:2015-09-03 15:42:53

标签: java hibernate one-to-one

我有一个hibernate管理实体:

@Entity
public class Parent  {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// (omitted useless details)

@OneToOne
@JoinColumn(name = "child_id", updatable = false)
private Child child;

// (omitted useless details)
}

-

@Entity
public class Child {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// (omitted rest...this is a POJO)
}

由于Child的更新责任是在其他地方管理的,因此我的目标是在保存父级时简单地更新子级。不幸的是,updatable = false上的@JoinColumn似乎被忽略了,保存了对父母和子女所做的任何更改。

如何才能实现仅以一对一的关系保存父级?

感谢任何帮助。

编辑:澄清,Child类也是@Entity,但是一个简单的POJO。父和子之间的关系是从父母那里单向的。

1 个答案:

答案 0 :(得分:2)

我对此进行了一段时间的研究并查看@JoinColumn注释的文档以及它所说的可更新/可插入属性...

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

这意味着设置updatable = false只会阻止更新外键(包含列)。保存父实体时,它还将保存附加到对象的所有子实体。

这意味着保存时附加到父实体的所有子属性也将保留。如果其他人可能已更新此子实体,则会带来另一个问题,但由于您正在保存附加了子实体的父实体,因此您将无意中覆盖对子对象所做的任何更改。

解决方案:

AFAIK解决这个问题的唯一方法是勤勉地保存你保存的对象,除非你真的需要保存/更新子实体。保持对象自包含,这是lazy / eager加载属性的缺点并保存相同的对象图。你也可以像另一张海报那样说并在保存前将子实体设置为null以防止任何更新,但很容易被遗漏。

如果您可以保存整个对象树(父实体和子实体),则可以添加一个使用@Version属性的属性来引入乐观并发。这样,如果任何实体被其他人更新,而您尝试保存旧版本,则会失败。

@Version
@Column(name=”version”)
private long version;
public long getVersion() { return version; }