2013-03-08 15 views
8

ho 2 classi denominate PurchaseList.java e PurchaseListItems.javaHibernate OneToMany, ManyToOne Mapping Dare nulla

devo mappare PurchaseList in PurchaseListItems

PurchaseList.java

@OneToMany(cascade = CascadeType.ALL) 
@JoinColumn(name="pl_id",referencedColumnName="id") 
private List<PurchaseListItems> purchaseListItems; 

PurchaseListItems.java

@ManyToOne 
@JoinColumn(name="pl_id") 
private PurchaseList purchaseListId; 

Tutto va bene ma sto ottenendo null in pl_id. Indicare dove sono errato

+0

JPA non gestisce le relazioni bidirezionali. Devi stabilire tu stesso la relazione inversa. Si noti inoltre che i mapping definiscono due relazioni unidirezionali indipendenti. Vedi la mia spiegazione sotto – bennidi

risposta

5

La mappatura definisce in realtà due relazioni unidirezionali indipendenti. Ciò che si vuole è una relation.The bidirezionale seguente codice stabilirà il rapporto bidirezionale

@OneToMany(cascade = CascadeType.ALL, mappedBy = "purchaseListId") 
@JoinColumn(name="pl_id",referencedColumnName="id") 
private List<PurchaseListItems> purchaseListItems; 

L'attributo mappedBy è necessaria in quanto non v'è alcun modo per il provider a determinare automaticamente che i rapporti specificati in realtà formano un unico rapporto. Si potrebbe usare il tipo Java del membro dell'istanza, ma se si hanno più membri dello stesso tipo. E ci sono molti scenari in cui hai due relazioni singole. Esempio:

OneToMany: Utente -> ForumThread (i fili creati dall'utente)

ManyToOne: ForumThread -> Utente (. L'utente che ha chiuso il filo ovviamente non necessariamente quello che ha iniziato il filo)

Queste sono due relazioni indipendenti e devono essere trattate come tali. Sareste piuttosto sorpresi se la vostra persistenza fornisse appena una relazione bidirezionale da ciò solo perché i tipi e la molteplicità corrispondevano.

Si noti inoltre che le relazioni bidirezionali non vengono gestite automaticamente da alcun provider JPA, ovvero che il lato inverso non viene automaticamente aggiornato/impostato nel modello a oggetti e quindi non nel db. Devi farlo da solo. A proposito, in tutti i miei progetti i rapporti bidirezionali sono stati un rompicoglioni e penso che sia consigliabile evitarli.

+6

Con hibernate4 (non sono sicuro della ver precedente) mappedby e JoinColumn non possono essere usati insieme. – Chandru

+0

Ho la stessa esperienza di https://stackoverflow.com/users/1047493/bennidi. Se eviterò relazioni bidirezionali e recupererò tutto "manualmente". Avevo finito due tre volte più veloce. – hariprasad

0

La specifica jpa sembra buona, ma verificare che nel database sia stata fornita una relazione genitore/figlio valida. Se non c'è un riferimento, restituirà null.

0

provare questo

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "purchaseListId") 
0

Verificare che sia stato popolato purchaseListId con valore valido (un creato PurchaseList esempio) quando si crea un valore PurchaseListItems.

E 'meglio usare mappedBy come qui di seguito il codice per permettere molti-side per maintian il rapporto.

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "purchaseListId") 
@JoinColumn(name="pl_id",referencedColumnName="id") 
private List<PurchaseListItems> purchaseListItems; 
+0

No, non funziona Henry, cosa hai detto sopra. Mi manca qualcosa che non so. –

+0

@sainath Puoi spiegare cosa intendi con "Tutto va bene ma sto ottenendo null in pl_id."? vuoi dire che pl_id è nullo nel database o nell'istanza di PurchaseListItems caricata? –

+0

Nel database al momento dell'inserimento deve prendere l'id dagli acquisti e deve mettere al posto di pl-id. Ma invece di questo sta salvando null. –

0
for(PurchaseListItems item:purchaseListItemsList) 
item.purchaseListId(PurchaseList); 

Questo è quello che ho perso quando sto creando un oggetto.

Thnaks per le vostre risposte

0
  1. L'annotazione @JoinColumn appartiene sul lato @ManyToOne del rapporto - ma non sul lato @OneToMany - rimuoverlo dal lato @OneToMany.

  2. Cascade viene utilizzato per eseguire in cascata le operazioni DELETE/READ/UPDATE ..., ma non inserisce automaticamente la colonna ID sul lato "figlio" di una chiave esterna. Infatti, non popola i riferimenti java agli oggetti su entrambi i lati della relazione FK. È necessario configurare manualmente i dati di relazione su entrambi i lati delle relazioni bidirezionali:

    myPurchaseListItem.setPurchaseList (myPurchaseList);
    myPurchaseList.setPurchaseListItem (myPurchaseListItem);

    Dal JPA 2 spec:

    rapporti bidirezionali tra entità gestite saranno persistenti sulla base di riferimenti detenute dal lato possessore della relazione. È responsabilità dello sviluppatore mantenere i riferimenti in memoria conservati sul lato proprietario e quelli mantenuti sul lato inverso in modo coerente l'uno con l'altro quando cambiano. Nel caso di relazioni unidirezionali one-to-one e one-to-many, è responsabilità dello sviluppatore assicurare (sic) che la semantica delle relazioni sia rispettata.[29]

    È particolarmente importante garantire che le modifiche all'inverso di una relazione abbiano come risultato aggiornamenti appropriati sul lato proprietario, in modo da garantire che le modifiche non vadano perse quando vengono sincronizzate con il database.

1

Per qualche ragione mappata non ha funzionato per me con Postgres SQL e Hibernate4

seguito mappatura lavorato

PurchaseList.java

@OneToMany(cascade = CascadeType.ALL) 
@JoinColumn(name="pl_id",nullable=false) 
private List<PurchaseListItems> purchaseListItems; 

PurchaseListItems.java

@ManyToOne 
@JoinColumn(name="pl_id", nullable=false,insertable=false,updatable=false) 
private PurchaseList purchaseListId; 

Nota: è necessario utilizzare l'identità o indicare esplicitamente la sequenza per le colonne id per postgres.

@GeneratedValue(strategy=GenerationType.IDENTITY) 
+0

All'interno della tabella il valore della colonna di join viene aggiornato, ma nell'oggetto entità sto anche ottenendo il valore come null –

Problemi correlati