2013-08-23 10 views
5

Ho bisogno del tuo aiuto per mappare la relazione in Hibernate di due tabelle usando l'annotazione @ElementCollection.JPA: come utilizzare l'annotazione @ElementCollection?

Il primo è la tabella padre
Nome tabella: Parent
DB Colonne

KEY1   Char  (first primary key field) 
KEY2   Char  (second primary key field) 
DESCRIPTION Char 
DEPENDENTID BigInt 

La seconda è la tabella dipendente
TableName: dipendenti
DB Colonne

PARENTID  BigInt (first primary key field) 
CODE   Char  (second primary key field) 
FIELD1  Char 
FIELD2  Char 

Ho bisogno di definire il PK per entrambe le tabelle con l'annotazione EmbeddedId, così ho creato due classi:

@Embeddable 
public class ParentPK implements Serializable 
{ 
    @Column(name="K1") 
    private String iK1; 
    @Column(name="K2") 
    private String iK2; 
    // I omit the constructor, getter, setter, equals, hashcode method 
} 

@Embeddable 
public class DependentPK implements Serializable 
{ 
    @Column(name="PARENTID") 
    private String iParentId; 
    @Column(name="CODE") 
    private String iCode; 
    // I omit the constructor, getter, setter, equals, hashcode method 
} 

e poi ho creato i due fagioli:
La classe per la tabella dipendente .
Si noti che in questa classe non voglio avere alcuna annotazione relazionale

@Entity 
@Table(name = "DEPENDENT") 
public class DependentBean implements Serializable 
{ 
    @EmbeddedId 
    private DependentPK iDependentPK; 
    @Column(name = "FIELD1") 
    private String iField1; 
    @Column(name = "FIELD2") 
    private String iField2; 
    // I omit the constructor, getter, setter methods 
} 

E la classe per la tabella padre

@Entity 
@Table(name = "PARENT") 
public class ParentBean implements Serializable 
{ 
    @EmbeddedId 
    ParentPK iParentPK; 
    @Column(name = "DESCRIPTION") 
    private String iDescription; 
    @Column(name = "DEPENDENTID") 
    private long iDependentId; 
    @ElementCollection 
    @CollectionTable(name="DEPENDENT", joinColumns={@JoinColumn(name="PARENTID", referencedColumnName="DEPENDENTID")}) 
    private Set<DependentBean> iDependentBeans = new HashSet<DependentBean>(); 
    // I omit the constructor, getter, setter methods 
} 

Quando provo a schierare ho ottenuto l'errore:

Caused by: org.hibernate.MappingException: Foreign key (FK9619C2A17B05CB2:DEPENDENT [iDependentBeans_PARENTID,iDependentBeans_CODE])) must have same number of columns as the referenced primary key (DEPENDENT [PARENTID,iDependentBeans_PARENTID,iDependentBeans_CODE])

Quindi sto facendo qualcosa di sbagliato, ma non riesco a immaginare cosa. Qualcuno potrebbe volermi aiutare, per favore?

risposta

7

@ElementCollection deve essere utilizzato con tipo di base o classe incorporabile, non per entità.

Il DependentBean è un'entità.

tenta di utilizzare uno a molti Mappatura e modificare lo schema

schema GENITORE

KEY1   Char  (PK) 
KEY2   Char  (PK) 
DEPENDENTID BigInt (PK) 
DESCRIPTION Char 

schema DIPENDENTE

CODE   Char  (PK) 
PARENTID  BigInt (FK) 
KEY1   Char  (FK) 
KEY2   Char  (FK) 
FIELD1  Char 
FIELD2  Char 

uno a molti mappatura

ParentPK

@Embeddable 
public class ParentPK { 
    @Column(name = "K1") 
    private String iK1; 
    @Column(name = "K2") 
    private String iK2; 
    @Column(name = "DEPENDENTID") 
    private long iDependentId; 
} 

ParentBean

@Entity 
@Table(name = "PARENT") 
public class ParentBean { 
    @EmbeddedId 
    ParentPK iParentPK; 

    @OneToMany(mappedBy = "parent") 
    List<DependentBean> iDependentBeans; 
} 

DependentBean

@Entity 
@Table(name = "DEPENDENT") 
public class DependentBean { 
    @Id 
    @Column(name = "CODE") 
    private String iCode; 

    @ManyToOne 
    @JoinColumns({ 
     @JoinColumn(name = "PARENTID", referencedColumnName = "iDependentId"), 
     @JoinColumn(name = "K1", referencedColumnName = "iK1"), 
     @JoinColumn(name = "K2", referencedColumnName = "iK2") }) 
    ParentBean parent; 
} 
+0

Prima di tutto grazie per la risposta. Ma ho visto che usando onetomany annotazione Hibernate crea un join quando si accede alla tabella genitore. Ho bisogno di accedere alla tabella dipendente solo quando si accede al suo attributo.Quindi, qual è il modo per farlo? – gpezzini

+0

Penso che tu usi @OneToMany (fetch = FetchType.EAGER), questo sicuramente farà un join come dici tu. Prova a utilizzare @OneToMany (fetch = FetchType.LAZY) e assicurati di accedere all'attributo prima di chiudere la sessione. Altrimenti, otterrai una LazyInitializationException. – study

+0

Salve, ma è possibile definire uno OneToMany tra le mie due tabelle ** Parent ** e ** Dependent **? Come si vede la tabella ** Parent ** ha il campo 'DEPENDENTID' che potrebbe essere collegato al campo 'PARENTID' della tabella ** Dipendente **. ** La tabella dipendente ** ha un altro campo chiave principale: "CODICE". Le due tabelle hanno le proprie chiavi primarie descritte utilizzando una classe incorporabile. Quindi, secondo lei, è possibile utilizzare l'annotazione @OneToMany in questo scenario? Ho provato in diversi modi senza successo e ho provato molte ricerche senza trovare nulla. Grazie in anticipo per il tuo tempo – gpezzini

Problemi correlati