Java Persistence/ManyToOne

author
3 minutes, 30 seconds Read

Una relazione ManyToOne in Java è quella in cui l’oggetto sorgente ha un attributo che fa riferimento a un altro oggetto, l’oggetto destinazione. Cioè il caso piuttosto tipico di Java in cui un oggetto detiene un riferimento ad un altro oggetto. Una relazione ManyToOne può essere specificata unidirezionale. Tuttavia, è tipico che l’oggetto di destinazione abbia la relazione inversa specificata all’oggetto sorgente. Questa sarebbe una specificazione di relazione OneToMany nell’oggetto di destinazione. Tutte le relazioni in Java e JPA sono unidirezionali, nel senso che se un oggetto sorgente fa riferimento ad un oggetto destinazione non c’è garanzia che l’oggetto destinazione abbia anche una relazione con l’oggetto sorgente. Questo è diverso da un database relazionale, in cui le relazioni sono definite attraverso chiavi esterne e interrogazioni tali che la query inversa esiste sempre.

In JPA una relazione ManyToOne è specificata attraverso l’annotazione @ManyToOne o l’elemento <many-to-one>. Un’annotazione @ManyToOne è tipicamente accompagnata da un’annotazione @JoinColumn. L’annotazione @JoinColumn specifica come la relazione dovrebbe essere mappata in (espressa in) un database. Il @JoinColumn definisce il nome della colonna chiave esterna (@JoinColumn(name = "...")) nell’oggetto sorgente che dovrebbe essere usata per trovare (unirsi) all’oggetto destinazione.

Se la relazione inversa OneToMany è specificata nell’oggetto destinazione, allora l’annotazione @OneToMany nell’oggetto destinazione deve contenere un attributo mappedBy per definire questa relazione inversa.

JPA definisce anche una relazione OneToOne, che è simile a una relazione ManyToOne, tranne che la relazione inversa (se fosse definita) è una relazione OneToOne. La differenza principale tra una relazione OneToOne e una ManyToOne in JPA è che una ManyToOne contiene sempre una chiave esterna dalla tabella dell’oggetto sorgente alla tabella dell’oggetto destinazione, mentre in una relazione OneToOne la chiave esterna può essere sia nella tabella dell’oggetto sorgente che nella tabella dell’oggetto destinazione.

Esempio di una relazione ManyToOne databaseEdit

EMPLOYEE (tabella)

EMP_ID FIRSTNAME LASTNAME SALARY MANAGER_ID
1 Bob Way 50000 2
2 Sarah Smith 75000 null

PHONE (tabella)

ID TYPE AREA_CODE P_NUMBER OWNER_ID
1 home 613 792-0000 1
2 lavoro 613 896-1234 1
3 lavoro 416 123-4444 2

Esempio di relazione ManyToOne annotazioniEdit

@Entitypublic class Phone { @Id private long id; ... // Specifies the PHONE table does not contain an owner column, but // an OWNER_ID column with a foreign key. And creates a join to // lazily fetch the owner @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="OWNER_ID") private Employee owner; ...}// Specification of the reverse OneToMany relationship in Employee@Entitypublic class Employee { @Id private long emp_id; ... // The 'mappedBy = "owner"' attribute specifies that // the 'private Employee owner;' field in Phone owns the // relationship (i.e. contains the foreign key for the query to // find all phones for an employee.) @OneToMany(mappedBy = "owner") private List<Phone> phones; ...

Esempio di relazione ManyToOne relazione XMLEdit

<entity name="Phone" class="org.acme.Phone" access="FIELD"> <attributes> <id name="id"/> <many-to-one name="owner" fetch="LAZY"> <join-column name="OWNER_ID"/> </many-to-one> </attributes></entity>

Vedi ancheEdit

  • Relazioni
    • Cascading
    • Lazy Fetching
    • Target Entity
    • Join Fetching
    • Lettura in blocco
    • Problemi comuni
  • OneToOne
    • Mappare una OneToOne utilizzando una tabella di unione
  • OneToMany

Problemi comuniModifica

La chiave esterna è anche parte della chiave primaria.Modifica

Vedi Chiavi primarie attraverso relazioni OneToOne.

La chiave esterna è anche mappata come una chiave base.Edit

Se usi lo stesso campo in due mappature diverse, in genere devi rendere una di esse di sola lettura usando insertable, updatable = false. Vedere Target Foreign Keys, Colonne di unione della chiave primaria, Chiavi primarie a cascata.

Errore di vincolo su insert.Edit

Questo tipicamente si verifica perché hai mappato in modo errato la chiave esterna in una relazione OneToOne. Vedi Target Foreign Keys, Primary Key Join Columns, Cascade Primary Keys. Può anche verificarsi se il vostro provider JPA non supporta l’integrità referenziale o non risolve i vincoli bidirezionali. In questo caso potrebbe essere necessario rimuovere il vincolo, o usare EntityManager flush() per assicurare l’ordine in cui i tuoi oggetti sono scritti.

Il valore della chiave esterna è nullEdit

Assicurati di impostare il valore del OneToOne dell’oggetto, se il OneToOne fa parte di una relazione bidirezionale OneToMany, assicurati di impostare il OneToOne dell’oggetto quando aggiungi un oggetto al OneToMany, JPA non mantiene le relazioni bidirezionali per te. Controllate anche di aver definito correttamente il JoinColumn, assicuratevi di non aver impostato insertable, updateable = false o usato un PrimaryKeyJoinColumn.

Similar Posts

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.