Sto usando Hibernate con annotazioni (in primavera), e ho un oggetto che ha una relazione ordinata, molti-a-uno che un oggetto figlio che ha una chiave primaria composta, un componente di cui è una chiave esterna all'id dell'oggetto genitore.@OneToMany e chiavi primarie composite?
La struttura simile a questa:
+=============+ +================+
| ParentObj | | ObjectChild |
+-------------+ 1 0..* +----------------+
| id (pk) |-----------------| parentId |
| ... | | name |
+=============+ | pos |
| ... |
+================+
Ho provato una varietà di combinazioni di annotazioni, nessuno dei quali sembra funzionare. Questo è il più vicino io sono stato in grado di elaborare con:
@Entity
public class ParentObject {
@Column(nullable=false, updatable=false)
@Id @GeneratedValue(generator="...")
private String id;
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER, cascade={CascadeType.ALL})
@IndexColumn(name = "pos", base=0)
private List<ObjectChild> attrs;
...
}
@Entity
public class ChildObject {
@Embeddable
public static class Pk implements Serializable {
@Column(nullable=false, updatable=false)
private String parentId;
@Column(nullable=false, updatable=false)
private String name;
@Column(nullable=false, updatable=false)
private int pos;
@Override
public String toString() {
return new Formatter().format("%s.%s[%d]", parentId, name, pos).toString();
}
...
}
@EmbeddedId
private Pk pk;
@ManyToOne
@JoinColumn(name="parentId")
private ParentObject parent;
...
}
sono arrivato a questo dopo un lungo periodo di sperimentazione in cui la maggior parte dei miei altri tentativi ceduta entità che di ibernazione non riusciva nemmeno a caricare per vari motivi .
AGGIORNAMENTO: Grazie a tutti per i commenti; Ho fatto dei progressi. Ho apportato alcune modifiche e penso che sia più vicino (ho aggiornato il codice sopra). Ora, tuttavia, il problema riguarda inserto. L'oggetto genitore sembra salvare bene, ma gli oggetti figli non stanno salvando, e quello che sono stato in grado di determinare è che l'ibernazione non sta compilando la parte parentId della chiave primaria (composita) degli oggetti figli, quindi io ' m ottenendo un errore non-unico:
org.hibernate.NonUniqueObjectException:
a different object with the same identifier value was already associated
with the session: [org.kpruden.ObjectChild#null.attr1[0]]
sto popolando le name
e pos
attributi in mio codice, ma naturalmente io non conoscere l'ID genitore, perché non è stato ancora salvato. Qualche idea su come convincere l'ibernazione a riempirlo?
Grazie!
Buona fortuna. Un progetto su cui mi trovavo doveva abbandonare totalmente le chiavi composite a favore delle chiavi sintetiche a causa del scarso supporto di Hibernate. –
L'eccezione potrebbe essere causata dall'utilizzo dell'elenco <>. È necessario utilizzare Set <> per evitare la duplicazione della chiave utilizzando la definizione hashCode e equals. Hibernate considera due elementi "logicamente identici" in un elenco come due elementi, quindi ha causato l'eccezione. – Popeye