2012-03-31 12 views
8

I tienen una entidad asignada como siguiente:¿@ManyToMany (mappedBy = ...) + @OrderColumn es compatible con el 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; 

    ... 
} 

Tiene una clave compuesta (round_id, ordinal_nbr) para indicar el orden de los grupos en una ronda.

Ahora imagine una tabla de unión que contiene entidades que enlazan los grupos ordenados a través de una autorreferencia (de un grupo a otro):

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

Sé que es posible mapear @ManyToMany + @JoinTable + @OrderColumn para la entidad propietaria (lo que elijo):

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

pregunta:

Para el lado de propiedad, ¿es posible mapear la relación inversa @ManyToMany(mappedBy = ...) con un @OrderColumn también?

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

¿La especificación JPA 2 define para permitir o denegar esto?

Gracias


Update 1:

Lo anterior es esencialmente una estructura gráfica. He aquí un ejemplo:

IMAGE

La tabla contiene las entidades GroupLinks en caja. Cuando se mira solo a la entidad B2 Group, la lista parents contendrá (a,1,b,2) y (a,2,b,2). En cuanto a la lista children, contendrá (b,2,c,1), (b,2,c,2) y (b,2,c,3).

Como se puede ver las entidades en las listas de B2 no chocan entre sí, por lo que un @OrderColumn debería funcionar bien para ambas relaciones parents y children - al menos en teoría. Pero, ¿cuál es la práctica aquí (JPA)?

Tenga en cuenta que simplemente intentarlo en Hibernate y/o EclipseLink realmente no responde a la pregunta de si la especificación JPA 2 o un proveedor compatible con JPA debe o debe ser compatible con este escenario.


Actualización 2:

Tratando las asignaciones anteriores sobre los resultados de Hibernate en la siguiente excepción mapeo:

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 

Extracción de los @OrderColumn para parent_ordinal_nbr resultados en la misma excepción para la relación children . Parece que a Hibernate no le gustan las columnas de pedido que también se usan en claves externas.


Actualización 3:

probado con EclipseLink en GlassFish ... esto funciona, no hay excepciones de mapeo.

Esto plantea dos preguntas de seguimiento:

  1. ¿Se desautorizar el APP columnas de orden de clave externa? No tiene sentido para mí por qué no deberían simplemente funcionar ...
  2. ¿Es esto un error de Hibernate?

Respuesta

6

El javadoc or OrderColumn tiene la información que está buscando:

La anotación OrderColumn se especifica en el lado de la relación que hace referencia a la colección que el proceso será condenada. La columna de orden no está visible como parte del estado de la entidad o clase incrustable.

La anotación OrderBy se debe utilizar para pedidos que estén visibles como estado persistente y mantenidos por la aplicación. La anotación OrderBy no se utiliza cuando se especifica OrderColumn.

OrderColumn se utiliza para agregar una columna adicional a la tabla de unión, utilizada para mantener el orden de la lista. La columna de orden, como se menciona en javadoc, no es parte del estado de la entidad. En su caso, parece que desea ordenar los elementos de la lista por una de sus propiedades persistentes. En ese caso, debe usar la anotación OrderBy (o tener un getter que ordene la lista antes de devolverla).

+0

Cualquiera que sea el estado de una entidad significa ... pregunta de seguimiento está aquí: http://stackoverflow.com/questions/10054400/jpa-ordercolumn-and- visible-state-of-a-entity – Kawu

+0

Buena explicación. Verdaderamente muestra la diferencia entre OrderColumn y OrderBy. +1 –

0

En OpenJPA hay un problema con respecto @OrderColumn funciona, el funcionamiento de la recuperación, pero el ahorro de una entidad obtiene un error "objeto independiente", este error está asociado a la adición de esta anotación (@OrderColumn)

La solución es utilizar el comparador en la clase parent.getChildEntity para ordenar la lista de entidades hijo, por lo tanto, esto evita utilizar @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()); 
     } 

    }); 

solucionado :) John V, Col