2009-03-21 29 views
15

Tengo 2 entidades en JPA: entrada y comentario. La entrada contiene dos colecciones de objetos Comment.¿Cómo tener 2 colecciones del mismo tipo en JPA?

@Entity 
public class Entry { 
    ... 

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @IndexColumn(base = 1, name = "dnr") 
    private List<Comment> descriptionComments = new ArrayList<Comment>(); 

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @IndexColumn(base = 1, name = "pmnr") 
    private List<Comment> postMortemComments = new ArrayList<Comment>(); 

    ... 
} 

Para almacenar dichos objetos, JPA + Hibernate crea "Entrada" mesa "Comentario" mesa y SINGLE "Entry_Comment":

create table Entry_Comment (Entry_id integer not null, postMortemComments_id integer not null, pmnr integer not null, descriptionComments_id integer not null, dnr integer not null, primary key (Entry_id, dnr), unique (descriptionComments_id), unique (postMortemComments_id))

El almacenamiento de objetos fallar como descriptionComments_id y postMortemComments_id no puede ser "no nulo" al mismo tiempo.

¿Cómo almaceno un objeto que contiene dos colecciones del mismo tipo usando JPA + Hibernate?

Respuesta

13

Este es uno de los muchos errores de Hibernate (HHH-3410 para ser precisos).

He logrado arreglarlo agregando anotaciones @JoinTable a relaciones @OneToMany, cada una tiene su propio nombre de tabla.

En su caso, se vería así:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
@JoinTable(name="entity_descriptioncomments") 
@IndexColumn(base = 1, name = "dnr") 
private List<Comment> descriptionComments = new ArrayList<Comment>(); 

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
@JoinTable(name="entity_postmortemcomments") 
@IndexColumn(base = 1, name = "pmnr") 
private List<Comment> postMortemComments = new ArrayList<Comment>(); 

Nota: debe agregar @IndexColumn anotación también (debido a otro problema de Hibernate con múltiples bolsas EAGER: HHH-1718/EJB-346).

+0

¿Y cómo haces que esta relación sea bidireccional? –

4

Para almacenar 2 colecciones como la de JPA con DataNucleus (http://www.datanucleus.org) harías exactamente lo mismo que has hecho. No tiene una anotación @JoinTable, por lo tanto, se debe colocar un FK en Comment para cada una de las colecciones. Si realmente tiene @JoinTable en algún lugar (o XML equivalente), entonces también sería útil establecer los nombres de las tablas de unión respectivas (una para cada colección) (para que tengan su propia tabla de combinación). Tener una tabla de unión compartida entre 2 colecciones también es posible en DataNucleus, pero eso no es una JPA estándar, sino una extensión de proveedor.

Cómo que se asigna a Hibernate no tengo ni idea, pero entonces esto es por lo que la APP debe ser constante desde ese es el punto de tener una especificación ;-)

2

Hay una falla con la asignación actual del modelo de datos/dominio modelo de punto de vista: que actaully tiene una sola @OneToMany relación entre entrada y comentario. Y comentario entidad debe tener un atributo llamado más tipo que tiene 2 valores: 'Descripción' o 'post-mortem '.

Estar en línea con su actual aplicación de entrada entidad es posible que desee considerar la descomposición comentario entidad en 2 diferentes entidades (posiblemente usando características de herencia JPA) y el uso de @JoinTable anotación en entrada.

0

Si todo lo que le interesa es pedir, ¿qué le parece si configura las dos definiciones de columna de índice para que tengan el mismo nombre?

+0

Lo intenté. Hibernate todavía lanza una excepción. –

Cuestiones relacionadas