2014-08-31 66 views
0

我需要使用JPA/Hibernate建立兩個實體之間的關係:ChildFather,兩者都擴展了實體User。一個父親可以沒有孩子,每個孩子都必須有一個父親。我可以插入沒有問題的父親,但不能添加屬於我之前插入的父親的孩子。這是我如何添加子:如何使用JPA映射相同超類的實體之間的關係?

SelectStatement ss = new SelectStatement(); 
    ss.manager.clear(); 
    Father father = ss.getFather(socialId); 

    Child child = new Child(); 
    //Set some parameters 
    dependente.setFather(father); 

    titular.addChild(child); 
    ss.manager.refresh(titular); 
    ss.manager.persist(dependente); 
    ss.manager.getTransaction().begin(); 
    try{ 
     ss.manager.getTransaction().commit(); 
     ss.close(); 
     return true; 
    } 
    catch(RollbackException e){ 
     ss.close(); 
     return false; 
    } 

類用戶:

@Entity 
    @Inheritance (strategy = InheritanceType.JOINED) 
    public class User{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int pk_user; 

    @Column 
    private String name;   
} 

類的父:

@Entity 
public class Father extends User{ 


    @OneToMany(mappedBy="father") 
    @LazyCollection(LazyCollectionOption.FALSE) 
    private Collection <Child> childs; 

    @Column(nullable=true, unique=true) 
    private String social_id; 


    public void addChild(Child child){ 
     this.childs.add(child); 
    }  
} 

類兒童:

@Entity 
public class Child extends User{ 

    //Here is the problem! 
    @ManyToOne(optional = false) 
    @JoinColumn(name = "pk_user") 
    private Father father; 

} 

PS:我已刪除/爲了清晰起見改變了一些屬性,所以不要擔心回合不存在的get/set方法等。

以下代碼會產生錯誤「應使用insertable = false,updatable = false」。如果我使用,我收到錯誤「無法添加或更新子行」。

我可以擦除類User並將其所有屬性複製到Father和Child,從而爲此問題創建解決方案。但我真正的父/子/用戶類很複雜,以避免這樣做。

謝謝。

回答

0

我發現了這個問題。我爲2列使用了相同的列名。現在在子表中,對於每個孩子,我都有一個指向超類的pk_user,以及指向孩子父親的「pk_father」。

@Entity 
public class Child extends User{ 

    //name has to be != then pk_user 
    @ManyToOne(optional = false) 
    @JoinColumn(name = "pk_father") 
    private Father father; 

} 
1

我有類似的代碼,它爲我工作正常(我在JTA環境):

create Father; 
em.persist(fatherInstance); 
em.flush(); //(with this I become assured, that the father is present in database) 
create child; 
em.persist(childInstance); 
em.flush(); 

,做你真正需要的能力延遲加載你的孩子的掛名場?如果需要,我想通過使用@JoinColumn(nullable=false)會更好。

但爲了更好的理解問題 - 最好是看到確切的代碼。

+0

謝謝伊利亞。我找到了問題併發布爲答案。我試過你的代碼,最初'flush()'啓動了一個TransactionRequiredException。但是,如果'flush()'在'getTransaction()。begin();之後''比一切正常。不過,我仍然不清楚爲什麼我必須使用'flush()'。每筆交易堅持一個對象就能很好地工作。 – 2014-09-01 19:18:29

+0

關於延遲加載,實際的代碼不是延遲加載,只是爲了方便。每次我加載一個父對象時,我都會使用他所有的子對象,並且我知道一次不會有很多子對象和一個父對象,所以我不認爲這會是一個問題。爲什麼使用'@JoinColumn(nullable = false)'比'@LazyCollection(LazyCollectionOption.FALSE)'更好? – 2014-09-01 19:23:10

相關問題