2012-03-31 14 views
8

Mam podmiot mapowane następująco:Czy @ManyToMany (mappedBy = ...) + @OrderColumn obsługiwane przez JPA?

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

    ... 
} 

Ma kompozytowa klucz (round_id, ordinal_nbr) wskazać kolejność grup w rundzie.

Teraz wyobraź sobie dołączyć tabelę zawierającą elementy, które łączą zamówionego grup poprzez odniesienie siebie (od grupy):

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

wiem, że to możliwe map @ManyToMany + @JoinTable + @OrderColumn dla podmiotu posiadania (cokolwiek wybiorę):

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

Pytanie:

Czy dla posiadanej strony można mapować relację odwrotną @ManyToMany(mappedBy = ...) z @OrderColumn?

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

Czy specyfikacja JPA 2 określa, aby zezwolić na to lub odmówić?

Dzięki


aktualizacji 1:

Powyższa struktura jest zasadniczo wykresu. Oto przykład:

IMAGE

tabela GroupLinks zawiera pudełkowej podmiotów. Przyglądając się tylko jednostce B2 Group, lista parents będzie zawierać (a,1,b,2) i (a,2,b,2). Jeśli chodzi o listę children, będzie ona zawierała (b,2,c,1), (b,2,c,2) i (b,2,c,3).

Jak widać podmiotów w wykazach B2 nie zderzą, więc @OrderColumn powinien działać dobrze dla obu związkachparents i children - przynajmniej w teorii. Ale jaka jest tutaj praktyka (WZP)?

Należy zauważyć, że po prostu próbowanie go na Hibernate i/lub EclipseLink tak naprawdę nie odpowiada na pytanie, czy specyfikacja JPA 2 lub dostawca zgodny z JPA powinien lub musi obsługiwać ten scenariusz.


Aktualizacja 2:

Próby powyższe mapowania na wyniki hibernacji następującym wyjątkiem odwzorowywania:

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 

Wyjmowanie @OrderColumn dla parent_ordinal_nbr wyniki w tym samym wyłączenia dla związku children . Wygląda na to, że Hibernate nie lubi kolumn zamówienia, które są również używane w kluczach obcych.


Update 3:

Testowane z EclipseLink na GlassFish ... to działa, żadnych wyjątków mapowania.

To podnosi dwa nawiązanie pytania:

  1. Czy JPA niepozwalające kolumn klucza obcego zamówienie? Nie ma dla mnie sensu, dlaczego nie powinny po prostu działać ...
  2. Czy jest to błąd Hibernacji?

Odpowiedz

6

The javadoc or OrderColumn ma informacji szukasz:

OrderColumn Adnotacja jest określona na stronie relacji która odwołuje kolekcję, która ma zostać uporządkowane. Kolumna zamówienia nie jest widoczna jako część stanu encji lub klasy emulowalnej .

Przy zamówieniu należy użyć adnotacji OrderLy, która jest widoczna jako trwała i przechowywana przez aplikację. Adnotacja OrderBy nie jest używana, gdy określono OrderColumn.

Kolumna zamówienia służy do dodania dodatkowej kolumny do tabeli łączenia, służącej do utrzymywania porządku na liście. Kolumna zamówienia, jak wspomniano w javadoc, nie jest częścią stanu encji. W twoim przypadku wydaje się, że chcesz zamówić elementy na liście według jednej z ich trwałych właściwości. W takim przypadku musisz użyć adnotacji OrderBy (lub gettera sortującego listę przed zwróceniem go).

+0

Cokolwiek stan podmiotu oznacza nawiązanie ... pytanie jest tutaj: http://stackoverflow.com/questions/10054400/jpa-ordercolumn-and- stan widoczny-jednostki-podmiotu – Kawu

+0

Dobre wyjaśnienie. Naprawdę pokazuje różnicę między OrderColumn i OrderBy. +1 –

0

W OpenJPA istnieje problem odnośnie @OrderColumn, operacja pobierania działa, ale oszczędność podmiot dostaje błąd „wolnostojący obiekt”, ten błąd jest związany z dodaniem tej adnotacji (@OrderColumn)

Rozwiązaniem jest Aby użyć komparatora w klasie parent.getChildEntity, aby uporządkować listę encji podrzędnych, unika się w ten sposób używania kolumny @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()); 
     } 

    }); 

rozwiązać :) Jan V, Col

Powiązane problemy