Hibernate @OneToOne with updatable = false 仍在更新

Hibernate @OneToOne with updatable = false still updating

我有一个休眠管理的实体:

@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 的更新责任在别处管理,我的目标是在保存父级时简单地 更新子级。不幸的是,@JoinColumn 上的 updatable = false 似乎被忽略了,保存了对父项和子项所做的任何更改。

如何实现只保存一对一关系中的父对象?

感谢任何帮助。

编辑:澄清一下,Child class 也是一个 @Entity,但是是一个简单的 POJO。 Parent 和 Child 之间的关系是单向的。

我研究了很长时间,并查看了@JoinColumn 注释的文档和它说的 updatable/insertable 属性...

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

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

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

解决方案:

AFAIK 解决此问题的唯一方法是对您保存的对象勤奋,除非您确实需要 saving/updating 子实体不需要。保持对象自包含,这是 lazy/eager 加载属性和保存相同对象图的缺点。您也可以像另一位发帖人所说的那样,在保存之前将子实体设置为 null 以防止任何更新,但很容易被遗漏。

如果您可以保存整个对象树(父实体和子实体),您可以添加一个 属性,它利用 @Version 属性引入开放式并发。这样,如果任何实体已被其他人更新,而您试图保存旧版本,它将失败。

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