2012-03-31 41 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,山口