一对一映射的java Hibernate合并问题
我有一个用InheritanceType映射的类层次结构。加入Hibernate(最终版本3.5.6)和JPA2.0-
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class A{
private Long id;
@OneToOne
@JoinColumn(name = "foo_id", nullable = false)
private Foo foo;
...
}
@Entity
@PrimaryKeyJoinColumn(name = "B_ID")
public class B{
...
}
@Entity
@PrimaryKeyJoinColumn(name = "C_ID")
public class C{
...
}
并且Foo
实体是-
@Entity
public class Foo{
@Id
private Long id;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "foo")
private A a
// getters / setters omitted
}
现在,我将实体Foo
引用B
保存到字段“a”中。稍后我想用类C
的引用将Foo的实例更新为属性“a”,所以我所做的是-
loadedFooInstance.setA(new C());
entityManager.merge(loadedFooInstance);
但我注意到的是,在分配C之前,它不会删除分配给该Foo对象的原始B对象。因此,在分配新实例之前,我需要手动删除分配给该Foo实例的A的所有引用
但是我相信hibernate一定有办法处理这样的场景,我在映射中遗漏了一些东西。
我的地图有什么问题吗。。或者这种映射可以用更好的方式实现,所以我不需要处理这种手工工作
# 1 楼答案
此架构中的某些内容不正确。当您删除B时,您希望删除Foo,因此A是关系的拥有方。所以如果没有B的存在,Foo就不应该存在。但是你现在所做的是从Foo中删除B,因此违反了关系,因为现在没有B。你应该遵循拉尔夫的建议2。建议#1行得通,但显然富应该是拥有方。而级联也将从映射的旁边工作。您定义的关系不正确
编辑:
要将Foo中的现有B设置为C: 这几乎与拉尔夫早期的建议相似
# 2 楼答案
您的OneToOne关系由A方管理,而不是由Foo方管理。因此,您需要更改A端的关系(因为hibernate只关注管理关系的一端)
另一种方法是更改管理关系的一方:
但这也会改变你的数据库布局