2010-06-02 10 views
21

Sto cercando di usare l'annotazione @OrderColumn con Hibernate 3,5JPA 2.0 @OrderColumn annotazioni in Hibernate 3.5

@OneToMany(mappedBy = "parent",fetch=FetchType.EAGER, cascade=CascadeType.ALL) 
@OrderColumn(name = "pos") 
private List<Children> childrenCollection; 

Quando il recupero dei dati, tutto funziona bene. Ma non posso farlo riordinare gli elementi nella Lista e salvare il nuovo ordine nel database.

+0

Potete mostrare come si fa ri-ordinare la vostra lista e salvare torna al database ??? –

+0

Ho provato a creare un nuovo ArrayList e parent.setChildrenCollection (newList) Ho provato Collections.sort nell'elenco recuperato. Ho anche provato a rimuovere oggetti nulli dalla raccolta. Non è successo niente. Altre modifiche genitoriali sono state salvate nel database, ma non è successo nulla con l'elenco. –

+0

non è Hibernate 3.5 per JPA 1.0 e @OrderColumn è JPA 2.0 ?! –

risposta

25

La combinazione di @OneToMany (mappedBy = "...") e @OrderColumn non è supportata da Hibernate. Questo problema di JIRA tiene traccia di una richiesta di un messaggio di errore più evidente quando viene utilizzata questa combinazione non valida: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5390

Penso che questo non sia supportato principalmente perché è uno strano modello relazionale. Le annotazioni precedenti indicano che il lato "uno" della relazione determina in che modo la relazione verrà scaricata nel database, ma l'ordine/posizione è disponibile solo sul lato "molti" esaminando l'elenco. Ha più senso per il "più" lato avere la relazione, dal momento che quella parte conosce sia l'appartenenza che l'ordine degli elementi.

dell'hibernate annotazioni documenti descrivono questa situazione in dettaglio:

http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-hibspec-collection-extratype-indexbidir

La soluzione è rimuovere l'attributo "mappedBy", che causerà l'associazione di utilizzare la strategia di join tabella predefinita invece di un colonna sulla tabella di destinazione. È possibile specificare il nome della tabella di join utilizzando l'annotazione @JoinTable.

L'effetto netto di questo cambiamento è che il "molti" lato della relazione determina ora come viene mantenuta la relazione. Il codice java deve garantire che l'Elenco sia aggiornato correttamente, poiché Hibernate ignorerà ora il lato "uno" durante il lavaggio delle entità.

Se si vuole ancora avere il lato "uno" accessibili in Java, la mappa con

@ManyToOne 
@JoinColumn(name="...", insertable=false, updatable=false, nullable=false) 
+4

È divertente che l'esempio "ufficiale" per le colonne indice esplicite utilizzi esattamente la combinazione '@OneToMany (mappedBy =" ... ")' + '@ OrderColumn' (vedere l'esempio 7.8 in http: //docs.jboss.org/hibernate/core/3.6/reference/it-US/html/collections.html # collections-indexed) –

+2

Dopo questa risposta è stato concordato che la situazione deve comunque essere supportata. Gail Badner: "Sono d'accordo che questo @OneToMany (mappedBy =" ... ") dovrebbe essere supportato." –

+1

C'è un altro provider JPA (come Eclipselink) che supporta '@OneToMany (mappedBy =" ... ")'? – deamon

3

Si dovrebbe cercare di specificare OrderColumn sul proprietario dell'associazione. O nella tua mappatura hai messo il proprietario sul figlio, il proprietario dovrebbe essere il genitore (in una associazione bidirezionale, il proprietario è quello che non ha la parola chiave mappedBy, qui metti questa parola chiave sulla classe del genitore, poi vuoi dire che la classe del genitore non è il proprietario)

Nella classe dei bambini dovresti avere la parola chiave mappedBy su parentCollection. Ma non sui bambini. Raccolta.
E nella classe genitore si dovrebbe avere la @JoinTable annotazione, qualcosa di simile:

@OneToMany(mappedBy = "parent",fetch=FetchType.EAGER, cascade=CascadeType.ALL) 
@OrderColumn(name = "pos") 
@JoinTable(name = "<NAME_OF_YOUR_TABLE>", joinColumns = @JoinColumn(<JOIN_COLUMNS_...>) 
private List<Children> childrenCollection; 
9

fare qualcosa di simile:

@Entity 
class Parent { 

    @OneToMany 
    @OrderColumn(name = "pos") 
    List<Child> children; 
} 

@Entity 
class Child { 

    @ManyToOne 
    Parent parent; 
    @Column(name = "pos") 
    Integer index; 

    @PrePersist 
    @PreUpdate 
    private void prepareIndex() { 
     if (parent != null) { 
      index = parent.children.indexOf(this); 
     } 
    } 
} 
+2

Penso che in prepareIndex() dovrebbe essere modificato in index = parent.children.indexOf (this); if (index == -1) index = parent.children.size(); – cn123h

Problemi correlati