[英]Hibernate merge issue with one to one mapping
我在JPA 2.0的Hibernate(最終版3.5.6)中通過InheritanceType.JOINED映射了一個類層次結構-
@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
}
現在,我將引用B
的實體Foo
保存到字段“ a”。 稍后,我想將類C
引用更新為Foo實例,以引用屬性“ a”,所以我所做的是-
loadedFooInstance.setA(new C());
entityManager.merge(loadedFooInstance);
但是我注意到的是-在分配C之前,它不會刪除分配給該Foo對象的原始B對象。因此,我需要在分配新實例之前手動刪除分配給該Foo實例的A的所有引用。
但是我相信休眠必須有應對這種情況的方法,並且我在映射中遺漏了一些東西。 我的映射中有什么問題嗎?還是可以通過更好的方式實現這種映射,所以我不需要處理此類手動工作。
您的OneToOne關系飛船由A側而不是Foo側管理。 因此,您需要在A端更改關系(因為休眠狀態僅關注關系管理的那一側)
A old = loadedFooInstance.getA();
oldA.setFoo(null);
C c = new C();
c.setFoo(loadedFooInstance);
/*and it is good practic to update foo too*/
loadedFooInstance.setA(c);
另一種方法是更改管理關系的一方:
public abstract class A{
...
@OneToOne(mappedBy = "a")
private Foo foo;
...
}
public class Foo{
...
@OneToOne
@JoinColumn(name = "a_id", nullable = false)
private A a
...
}
但這也會改變您的數據庫布局!
此架構中的某些內容不正確。 當您刪除B時,您要刪除Foo,因此A是關系的所有者。 因此,如果沒有B,則Foo不應該存在。 但是您現在正在做的是從Foo中刪除B,因此違反了關系,因為現在沒有B。您應該遵循Ralph的建議2。 建議1可以很好地工作,但顯然Foo應該是所有者。 並且級聯也將在並排映射中起作用。 您定義的關系不正確。
編輯:
為了將Foo中現有的B設置為C:這幾乎類似於Ralph的較老的Advice#1
Foo foo = entityManager.find(Foo.class, id);
B b = foo.getA();
entityManager.remove(b); //Explicitly remove or B still remains in database as B is the owning side
C c = new C();
c.setFoo(foo);
entityManager.persist(c); //c is the owning side, hence save c and not foo
entityManager.refresh(foo);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.