2012-03-31 40 views
8

我有映射爲以下實體:是由JPA支持的@ManyToMany(mappedBy = ...)+ @OrderColumn?

@Entity 
@Table(name = "Groups") 
@IdClass(value = GroupId.class) 
public class Group implements Serializable 
{ 
    @Id 
    @Column(name = "round_id") 
    private Integer roundId; 

    @Id 
    @Column(name = "ordinal_nbr") 
    private Integer ordinalNbr = 0; 

    ... 
} 

它有一個複合鍵(round_id, ordinal_nbr)以指示組中的圓形的順序。

現在想象一下,一個連接包含通過自我引用(從集團到集團)連接有序組實體表:

CREATE TABLE GroupLinks 
(
    parent_round_id INTEGER NOT NULL, 
    parent_ordinal_nbr SMALLINT NOT NULL, 
    child_round_id INTEGER NOT NULL, 
    child_ordinal_nbr SMALLINT NOT NULL, 
    PRIMARY KEY (parent_round_id, parent_ordinal_nbr, child_round_id, child_ordinal_nbr), 
    FOREIGN KEY (parent_round_id, parent_ordinal_nbr) REFERENCES Groups (round_id, ordinal_nbr), 
    FOREIGN KEY (child_round_id, child_ordinal_nbr) REFERENCES Groups (round_id, ordinal_nbr) 
); 

我知道這是可能映射@ManyToMany + @JoinTable + @OrderColumn爲擁有實體(無論我選擇):

@ManyToMany 
@JoinTable(name = "GroupLinks", joinColumns = {@JoinColumn(name = "parent_round_id", referencedColumnName = "round_id"), @JoinColumn(name = "parent_ordinal_nbr", referencedColumnName = "ordinal_nbr")}, inverseJoinColumns = {@JoinColumn(name = "child_round_id", referencedColumnName = "round_id"), @JoinColumn(name = "child_ordinal_nbr", referencedColumnName = "ordinal_nbr")}) 
@OrderColumn(name = "child_ordinal_nbr") 
private List<Group> children; 

問:

對於自有方面,是否支持將@ManyToMany(mappedBy = ...)@OrderColumn的相反關係映射?

@ManyToMany(mappedBy = "parents") 
@OrderColumn(name = "parent_ordinal_nbr") 
private List<Group> parents; 

JPA 2規範是否定義允許或拒絕?

由於


更新1:

上面基本上是一個圖形結構。這裏有一個例子:

IMAGE

GroupLinks表包含盒裝實體。當僅查看B2 Group實體時,parents列表將包含(a,1,b,2)(a,2,b,2)。至於children列表,它將包含(b,2,c,1),(b,2,c,2)(b,2,c,3)

正如你可以看到的B2名單不會發生碰撞的實體,這樣的@OrderColumn應該工作沒關係的雙方關係parentschildren - 至少在理論上。但是這裏有什麼實踐(JPA)?

請注意,僅僅在Hibernate和/或EclipseLink上進行嘗試並不能真正回答JPA 2規範或JPA兼容提供程序是否應支持此方案的問題。


更新2:

試穿休眠結果上述映射在下面的映射異常:

Caused by: org.hibernate.MappingException: Repeated column in mapping for collection: com.kawoolutions.bbstats.model.Group.parents column: parent_ordinal_nbr 
    at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:340) 
    at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:363) 
    at org.hibernate.mapping.Collection.validate(Collection.java:320) 
    at org.hibernate.mapping.IndexedCollection.validate(IndexedCollection.java:89) 
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1291) 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1729) 
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:84) 
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904) 
    ... 9 more 

卸下@OrderColumnparent_ordinal_nbr結果在相同的異常爲children關係。看起來Hibernate不喜歡在外鍵中使用的命令列。


更新3:測試使用的EclipseLink在GlassFish

...這個工程,沒有映射例外。

這帶來兩個後續問題:

  1. 是否JPA禁止外鍵順序列?它沒有任何意義,爲什麼他們不應該簡單地工作...
  2. 這是一個Hibernate的bug?

回答

6

javadoc or OrderColumn有你要找的信息:

的OrderColumn註釋的 關係引用的集合,是要有序的邊指定。 訂單列作爲實體或 可嵌入類的一部分不可見。

OrderBy註釋應該用於持久狀態並由應用程序維護的排序。 OrderCy 註釋在指定OrderColumn時不使用。

OrderColumn用於向連接表中添加一個額外的列,用於維護列表的順序。在javadoc中提到的order列不是實體狀態的一部分。在你的情況下,你似乎想要通過其持久屬性之一來排列列表中的元素。在這種情況下,您必須使用OrderBy批註(或者在返回之前有一個對列表進行排序的getter)。

+0

無論實體的狀態表示...的後續問題是在這裏:http://stackoverflow.com/questions/10054400/jpa-ordercolumn-and-可見的實體狀態 – Kawu 2012-04-07 12:18:16

+0

好的解釋。真正顯示OrderColumn和OrderBy之間的區別。 +1 – 2014-11-17 10:26:29

0

OpenJPA中有一個問題關於@OrderColumn,檢索操作工作,但節省了實體得到一個錯誤「脫管對象」,這個錯誤被關聯到添加此註釋(@OrderColumn)

的解決方案是在parent.getChildEntity類中使用比較器來排序子實體列表,這樣就避免了使用@OrderColumn。

Collections.sort(this.child, new Comparator<class_type>() { 
@Override 
     public int compare(class_type p1, class_type p2) { 
      return (int) (p1.getId() - p2.getId()); 
     } 

    }); 

解決:)約翰·V,山口