簡體   English   中英

一對一映射的Hibernate合並問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM