2013-01-08 23 views
4

我有我的如下關係的問題:JPA一對多 - 列表不更新後添加/刪除對象,但堅持DB

我(我使用JPA不休眠!)有1:N關係(父母:子女)。 在JSP網站上,會顯示父級和子級。 如果我加載JSP-Site(FIRST TIME)並用Child保存Parent,則一切正常,Parent將被保存,Child也將被保存到DB和Foreign Key中。 之後,第二個JSP站點與父項和子項一起顯示。

但是,如果我回到第一個網站並將第二個孩子(添加孩子)保存到現有父級,「childEntityList」仍然是舊的,我的意思是,新孩子不在此列表中,但插入在DB!

爲什麼「childEntityList」是舊的,不更新?!

我的代碼:

家長:

@Entity 
@Table(schema = "test", name = "Parent") 
@XmlRootElement 
@NamedQueries({...}) 
public class Parent implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "A_SEQ") 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "ID") 
    private int id; 

    @OneToMany(mappedBy = "p", fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    private List<ChildEntity> childEntityList = new ArrayList<ChildEntity>(); 
... 

    public List<ChildEntity> getChildEntityList() { 
     return childEntityList; 
    } 

    public void setChildEntityList(List<ChildEntity> childEntityList) { 
     this.childEntityList = childEntityList; 
    } 

    public void addChildEntityToParent(ChildEntity c) { 
     this.childEntityList.add(c); 
     if(c.getParent() != this) { 
      c.setParent(this); 
     } 
    } 

    public void removeChildEntityFromParent(ChildEntity c) { 
     childEntityList.remove(c); 
    } 
... 
} 

的孩子:

@Entity 
@Table(name = "Child") 
@NamedQueries({...}) 
public class ChildEntity implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "CHILD_ID") 
    private Long childId; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "PARENT_ID") 
    private Parent p; 
... 

    public Parent getParent() { 
     return p; 
    } 

    public void setParent(Parent p) { 
     this.p= p; 
     if(!p.getChildEntityList().contains(this)) { 
      p.getChildEntityList().add(this); 
     } 
    } 

保存碼:

Parent p = new Parent(...); 
    ChildEntity c = new ChildEntity(...); 
    p.addChildEntityToParent(c); 
    childEntityFacade.create(c); 

查看碼:

... 
    public doSomething(Parent p) { 
     super(p); 
    } 
    ... 
    List<ChildEntity> cList = p.getChildEntityList(); 
    System.out.print("Size: " + c.size()); 
    ... 

在查看代碼中,childList的大小每次都是相同的,即使我添加一個Child。 只有當我重新啓動服務器時,父項的所有子項纔會顯示!

父類中的「childEntityList」何時填充? 是否因爲「@OneToMany」而自動執行?

有人可以解釋它,並幫助我嗎?!

更新: 閱讀一些文章後,也許我有一個解決方案。 我應該合併EntityManager每次當我從父列表中添加/刪除一個子對象或我做一些其他的事情?

+0

在將***添加到子集合之前,您需要在子***上設置父記錄。另外,我強烈建議從一邊管理雙向關係。因爲你有管理分裂父母和孩子的記錄。 – Perception

+0

至於你的顯示問題,我會建議將子記錄添加到父級,然後保存父級。將孩子保存爲單獨的交易不會自動更新已實例化的父母中的列表。 – Perception

+0

我想我不明白你的意思。 父是存在的,我想添加一個或多個孩子給父母。 我用父類中的「addChildEntityToParent」來做到這一點。 **(合併問題正在幫助我)!** – user1956764

回答

4
+0

我完全一樣。在父類中我有addChildEntityToParent()方法,其中我添加的孩子和在子類中我有setParent()方法,其中我設置了孩子的父母。 – user1956764

+0

childEntityFacade.create(c)做了什麼?你什麼時候堅持父母?這是創建一個新的,你用什麼代碼添加一個孩子到現有的父母。如果您只合並孩子,那麼父母將不同步,您需要合併這兩者,或者正確編輯您的託管對象。 – James

0

是的,你需要合併母公司。我遇到同樣的問題,一旦合併父實體,問題就解決了。 你也需要保持雙方的關係。

1

(我使用JPA不休眠!)

我猜你的意思,你是不是使用Hibernate的API。
JPA只是一個持久性API規範,本身不做任何事情。
因此,如果您使用的是JPA ...你正在使用的東西做持久性。

JPA將持久化工作委託給持久化引擎,如Hibernate,EclipseLink,OpenJPA或其他。如果應用程序在JEE容器中運行,那麼應該爲您提供JPA實現:GlassFish(使用OpenJPA),WebLogic(使用EclipseLink) ),TomEE(使用OpenJPA)。

我應該合併的EntityManager每次當我添加/刪除從父親列表一個孩子 對象時...

你不合並EntityManager的;你用它來合併母公司:

parent = em.merge(parent); 

關於你的問題,當你以這種方式使用合併()...(而且由於映射指定CascadeType.ALL),然後根據需要刷新頁面(「網站1「),您應該使用更新的對象網絡獲取刷新的父對象,其中包含您在合併之前所做的更改(父級),包括任何新添加的子級。