2010-10-22 70 views
1

在我的Java EE 6的應用我的域模型中包含類似下面的雙向關係:JPA:的EclipseLink不持續的雙向關係數據庫

@Entity 
public class Users implements PrimaryKeyHolder<String>, Serializable { 
    @Id 
    private String username; 

    @ManyToMany(mappedBy= "users") 
    private List<Category> categories; 

    public List<Category> getCategories() { 
    if (categories == null) { 
     categories = new ArrayList<Category>(); 
    } 
    return Collections.unmodifiableList(categories); 
    } 

    public void addCategory(Category category) { 
    if (categories == null) { 
     categories = new ArrayList<Category>(); 
    } 

    categories.add(category); 
    if (!category.getUsers().contains(this)) { 
     category.addUser(this); 
    } 
    } 

    public void removeCategory(Category category) { 
    if (categories == null) { 
     categories = new ArrayList<Category>(); 
    } 

    categories.remove(category); 
    if (category.getUsers().contains(this)) { 
     category.removeUser(this); 
    } 
    } 

    public void setCategories(Collection<Category> categories) { 
    if (this.categories == null) { 
     this.categories = new ArrayList<Category>(); 
    } 

    for (Iterator<Category> it = this.categories.iterator(); it.hasNext();) { 
     Category category = it.next(); 
     it.remove(); 
     if (category.getUsers().contains(this)) { 
      category.removeUser(this); 
     } 
    } 

    for (Category category : categories) { 
     addCategory(category); 
    } 
    } 
} 

@Entity 
public class Category implements PrimaryKeyHolder<Long>, Serializable { 
    @Id 
    private Long id; 

    @ManyToMany 
    private List<User> users; 

    public List<User> getUsers() { 
    if (users == null) { 
     users = new ArrayList<User>(); 
    } 
    return Collections.unmodifiableList(users); 
    } 

    protected void addUser(User user) { 
    if (users == null) { 
     users = new ArrayList<User>(); 
    } 
    users.add(user); 
    } 

    protected void removeUser(User user) { 
    if (users == null) { 
     users = new ArrayList<User>(); 
    } 
    users.remove(user); 
    } 
} 

更新:我添加關係管理代碼。關係僅在用戶端設置,因此,添加/刪除方法在Categoriy類中受到保護。我通過setCategories在用戶上設置了類別。

Eclipselink正確地生成一個連接表CATEGORY_USERS。但是,它不會保留任何信息(它只會緩存信息)。例如。當我在實體管理器(例如用戶)上執行查找操作時,它會返回完整的對象圖(包括類別關係)。但是當我查看這些表時,信息不會更新(即使事務已提交)。我還在代碼中插入了刷新操作,但沒有成功。基本信息(如字符串,整數等欄)得到正確持續和更新。將日誌級別轉換爲FINE後,我可以看到沒有SQL語句分別針對關係表和連接表執行。但我確實看到了單向關係的SQL語句。

我的數據模型覆蓋了廣泛的單元測試,所有測試都通過了。我基本上在容器中執行相同的操作,提交事務,從數據庫重新加載實體並檢查關係是否正確設置,它們是什麼(我正在使用內存中的derby數據庫進行測試)。

我的應用服務器是Glassfish v3.1-b17。

任何幫助表示讚賞。 謝謝, Theo

+0

很少有問題。你在找哪個實體?基本信息是什麼意思?順便說一句,你缺少'@ JoinColumn'註釋。 – 2010-10-22 09:33:24

+1

我在找一個雙向關係的實體(例如在這個例子中的一個用戶)。通過基本信息,我指的是存儲在列中的類型(如字符串,整數等)。我更新了這個問題。感謝您指出了這一點。關於@JoinColumn:如果你忽略它,使用默認值,這是實體的PK。 – Theo 2010-10-22 09:48:56

+0

請顯示一些(僞)代碼,生成的SQL – 2010-10-22 11:28:14

回答

1

的努力,我終於得到了一個解決方案無盡小時後

4.-測試annoting關係:我只是改變了這種關係的擁有方,即我把的mappedBy屬性的類別實體是這樣的:

@ManyToMany(mappedBy= "categories") 
private List<User> users; 

對此的解釋可以發現here

3

確保您設置關係的雙方。規範要求應用程序設置關係的兩個方面,因爲JPA中沒有關係維護。

+0

我有關係維護代碼。但關係的任何一方都反映在數據庫中。所以這一定是另一個問題。 – Theo 2010-10-22 15:09:39

0

四點:

1.-當你有一個錯誤,這是更簡單的找到解決的一個實例(或單元測試)隔離開來再現錯誤。在你的情況下,你可以做一個更簡單的getter和setter的例子(例如,刪除不可修改的列表使用和其他不必要的方法來測試實際問題)。

2.-我建議您使用pojos,型號爲,沒有任何邏輯。所以,從pojos中刪除邏輯。

3.-我們使用eclipselink,我們沒有問題持續關係。所以,錯誤會出現在您的代碼中的可能性更大。與「cascade = javax.persistence.CascadeType.ALL

道歉,因爲我的英語不好:(

+0

是的,你說得對,我的代碼一定有問題。我沒有在我的pojos中放置任何邏輯。你看到的是用於管理實體的內存關係的關係管理代碼。 – Theo 2010-10-25 20:03:12