2011-08-22 8 views
9


devo lavorare con Hibernate e non molto sicuro di come risolvere questo problema, ho 2 tavolo con un rapporto 1..n come questo:
Hibernate chiave esterna come parte della chiave primaria

 
------- 
TABLE_A 
------- 
first_id (pk) 
second_id (pk) 
[other fields] 

------- 
TABLE_B 
------- 
first_id (pk)(fk TABLE_A.first_id) 
second_id (pk)(fk TABLE_A.second_id) 
third_id (pk) 
[other fields] 

Come posso gestirlo con Hibernate ???

Non ho idea di come gestire la chiave primaria per la seconda tabella ...

risposta

14

C'è un esempio che è completamente simile al tuo caso nello Hibernate reference documentation. Poco prima di questo esempio, troverai le spiegazioni. Ecco l'esempio, che corrisponde al tuo problema (Utente tabella A, e il cliente è la tabella B):

@Entity 
class Customer { 
    @EmbeddedId CustomerId id; 
    boolean preferredCustomer; 

    @MapsId("userId") 
    @JoinColumns({ 
     @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"), 
     @JoinColumn(name="userlastname_fk", referencedColumnName="lastName") 
    }) 
    @OneToOne User user; 
} 

@Embeddable 
class CustomerId implements Serializable { 
    UserId userId; 
    String customerNumber; 

    //implements equals and hashCode 
} 

@Entity 
class User { 
    @EmbeddedId UserId id; 
    Integer age; 
} 

@Embeddable 
class UserId implements Serializable { 
    String firstName; 
    String lastName; 

    //implements equals and hashCode 
} 

Nota: sarebbe molto più semplice di voi hanno avuto un identificatore surrogato per quei due tabelle. A meno che non sei costretto a gestire uno schema precedente, fai un favore a te stesso e usa le chiavi surrogate.

+0

Ma sai se ci sono dei problemi se cambio invece di mettere l'annotazione OneToOne sul Cliente, metti OneToMany sulla classe User ??? – rascio

+0

Dovrai renderlo un'associazione OneToMany/ManyToOne bidirezionale. –

+0

Così facendo, ottengo "Attributo" userId "ha un mapping non valido in questo contesto" all'interno di "CustomerId" –

3

Usa @PrimaryKeyJoinColumn e @PrimaryKeyJoinColumns annotazioni. Da Hibernate manual:

Il @PrimaryKeyJoinColumn annotazione fa dire che la chiave principale del soggetto è utilizzato come valore chiave esterna all'entità associata.

+2

Questo non risponde alla domanda dell'OP: ha una chiave primaria composta e alcuni campi di questa chiave primaria composita costituiscono una chiave esterna di un'altra entità. @PrimaryKeyJoinColumn viene utilizzato quando una chiave primaria è anche una chiave esterna. –

0
public class User implements Serializable { 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 5478661842746845130L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int id; 
} 
@Entity 
public class Author { 

    @Id 
    @Column(name = "AUTHOR_ID", nullable = false) 
    private int authorId; 
    @Column(name = "ENABLED", nullable = false, length = 1) 
    private boolean enabled; 

    @OneToOne 
    @MapsId 
    @JoinColumn(name = "AUTHOR_ID", referencedColumnName = "ID", nullable = false, insertable = false, updatable = false) 
    User user; 

    public boolean isEnabled() { 
     return enabled; 
    } 

    public void setEnabled(boolean enabled) { 
     this.enabled = enabled; 
    } 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

} 
+0

Il mio problema era leggermente diverso, nel mio caso l'entità "Utente" ha "username" e "email" come PK (quindi posso avere lo stesso nome utente associato a email diverse) e 'Autore' che ha lo stesso PK di' User' ('username',' email') e anche 'vatCode', non solo un' id' come nell'esempio;) – rascio