2012-03-31 17 views
8

Tôi có một thực thể ánh xạ như sau:Có phải @ManyToMany (mappedBy = ...) + @OrderColumn được JPA hỗ trợ không?

@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; 

    ... 
} 

Nó có một hỗn hợp chính (round_id, ordinal_nbr) để chỉ thứ tự của nhóm trong một vòng.

Bây giờ hãy tưởng tượng một tham gia bảng chứa các thực thể liên kết các nhóm lệnh thông qua một tự tham chiếu (từ Tập đoàn Group):

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) 
); 

Tôi biết nó có thể để ánh xạ @ManyToMany + @JoinTable + @OrderColumn cho đơn vị sở hữu (nào tôi chọn):

@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; 

Câu hỏi:

Đối với phía được sở hữu, có được hỗ trợ để ánh xạ mối quan hệ nghịch đảo @ManyToMany(mappedBy = ...) với một số @OrderColumn không?

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

Thông số JPA 2 có xác định để cho phép hoặc từ chối điều này không?

Cảm ơn


Cập nhật 1:

Trên đây thực chất là một cấu trúc đồ thị. Dưới đây là một ví dụ:

IMAGE

Bảng GroupLinks chứa các đối tượng đóng hộp. Khi chỉ xem thực thể B2 Group, danh sách parents sẽ chứa (a,1,b,2)(a,2,b,2). Đối với danh sách children, danh sách sẽ chứa (b,2,c,1), (b,2,c,2)(b,2,c,3).

Như bạn có thể thấy các đối tượng trong danh sách B2 sẽ không va chạm, vì vậy một @OrderColumn nên làm việc okay cho cả các mối quan hệparentschildren - ít nhất là về mặt lý thuyết. Nhưng thực hành ở đây (JPA) là gì?

Lưu ý rằng chỉ cần thử trên Hibernate và/hoặc EclipseLink không thực sự trả lời câu hỏi liệu thông số JPA 2 hoặc nhà cung cấp tương thích JPA có hay phải hỗ trợ kịch bản này.


Cập nhật 2:

Cố gắng ánh xạ trên về kết quả Hibernate trong các bản đồ ngoại lệ sau đây:

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 

Loại bỏ các @OrderColumn cho parent_ordinal_nbr kết quả trong ngoại lệ tương tự cho các mối quan hệ children . Có vẻ như Hibernate không thích các cột đơn đặt hàng cũng được sử dụng trong các khóa ngoại.


Cập nhật 3:

Thử nghiệm với EclipseLink trên GlassFish ... làm việc này, không có trường hợp ngoại lệ bản đồ.

Điều này đặt ra hai câu hỏi followup:

  1. Liệu JPA không cho phép các cột theo thứ tự quan trọng nước ngoài? Nó không có ý nghĩa với tôi tại sao họ không nên chỉ đơn giản là làm việc ...
  2. Đây có phải là lỗi Hibernate không?

Trả lời

6

Các javadoc or OrderColumn có các thông tin bạn đang tìm kiếm:

Chú thích OrderColumn được quy định ở mặt bên của mối quan hệ tham chiếu đến các bộ sưu tập mà là để được đặt hàng. Cột đơn hàng không hiển thị như một phần của trạng thái của đối tượng hoặc lớp có thể nhúng.

Chú thích OrderBy nên được sử dụng để đặt hàng hiển thị dưới dạng trạng thái liên tục là và được ứng dụng duy trì. Chú thích OrderBy không được sử dụng khi OrderColumn được chỉ định.

OrderColumn được sử dụng để thêm cột bổ sung vào bảng kết nối, được sử dụng để duy trì thứ tự của danh sách. Cột thứ tự, như đã đề cập trong javadoc, không phải là một phần của trạng thái thực thể. Trong trường hợp của bạn, có vẻ như bạn muốn đặt hàng các phần tử trong danh sách bởi một trong những thuộc tính liên tục của chúng. Trong trường hợp đó, bạn phải sử dụng chú thích OrderBy (hoặc có một trình thu thập để sắp xếp danh sách trước khi trả về nó).

+0

Dù tình trạng của một thực thể có nghĩa là ... câu hỏi của followup là ở đây: http://stackoverflow.com/questions/10054400/jpa-ordercolumn-and- trạng thái hiển thị-của-một-thực thể – Kawu

+0

Giải thích tốt. Thực sự cho thấy sự khác biệt giữa OrderColumn và OrderBy. +1 –

0

Trong OpenJPA có một vấn đề liên quan đến @OrderColumn hoạt động, các hoạt động lấy, nhưng tiết kiệm một thực thể nhận được một thông báo lỗi "đối tượng tách ra", lỗi này có liên quan để thêm chú thích này (@OrderColumn)

Giải pháp là để sử dụng bộ so sánh trong lớp parent.getChildEntity để sắp xếp danh sách thực thể con, do đó, việc này tránh sử dụng @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()); 
     } 

    }); 

Giải Quyết :) John V, Col