2009-03-21 10 views
15

Ho 2 entità in JPA: inserimento e commento. La voce contiene due raccolte di oggetti Comment.Come avere 2 raccolte dello stesso tipo in 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>(); 

    ... 
} 

Per memorizzare tali oggetti, JPA + Hibernate crea "Entry" tavolo, "Commento" tavolo e 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))

Memorizzazione di oggetti sicuro come descriptionComments_id e postMortemComments_id non può essere "non null" allo stesso tempo.

Come si memorizza un oggetto contenente due raccolte dello stesso tipo utilizzando JPA + Hibernate?

risposta

13

Questo è uno dei molti bug di Hibernate (HHH-3410 per la precisione).

Sono riuscito a risolverlo aggiungendo le annotazioni @JoinTable alle relazioni @OneToMany, ognuna con il proprio nome di tabella.

Nel tuo caso sarebbe simile a questa:

@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: è necessario aggiungere @IndexColumn annotazione pure (a causa della altra questione Hibernate con più sacchi EAGER: HHH-1718/EJB-346).

+0

E come si fa a rendere questa relazione bidirezionale? –

4

Per memorizzare 2 raccolte del tipo in JPA con DataNucleus (http://www.datanucleus.org) si farebbe esattamente come si è fatto. Non hai annotazione @JoinTable quindi un FK deve essere inserito in Comment per ciascuna delle raccolte. Se in realtà hai @JoinTable da qualche parte (o equivalente XML), allora anche i nomi delle rispettive tabelle di join (uno per ogni raccolta) funzionerebbero (quindi hanno una propria tabella di join). Anche in DataNucleus è possibile avere una tabella di join condivisa tra 2 raccolte, ma non è JPA standard, ma un'estensione del venditore.

Come che mappa Hibernate Non ne ho idea, ma allora questo è APP in modo deve essere coerente in quanto questo è il punto di avere una specifica ;-)

2

C'è un difetto con la mappatura corrente dal modello di dati/dominio punto di vista del modello: avete actaully un singolo@OneToMany rapporto tra Entrata e Commento. E Commento entità dovrebbe avere un altro attributo chiamato tipo che prende 2 valori: 'Descrizione' o 'post-mortem '.

Per essere in linea con il vostro attuale implementazione di Entry entità che si può prendere in considerazione abbattere commento entità in 2 entità diverse (possibilmente utilizzando le funzionalità di eredità JPA) e l'utilizzo di @JoinTable annotazione nei Entry.

0

Se tutto quello che ti interessa è l'ordine, che ne dici di configurare le due definizioni di colonne dell'indice per avere lo stesso nome?

+0

Ho provato. L'ibernazione genera ancora un'eccezione. –

Problemi correlati