Une relation ManyToOne
en Java est celle où l’objet source possède un attribut qui référence un autre objet, l’objet cible. C’est-à-dire le cas assez typique en Java où un objet détient une référence à un autre objet. Une relation ManyToOne
peut être spécifiée de manière unidirectionnelle. Cependant, il est typique que l’objet cible ait la relation inverse spécifiée en retour à l’objet source. Il s’agit alors d’une relation OneToMany
spécifiée dans l’objet cible. Toutes les relations dans Java et JPA sont unidirectionnelles, en ce sens que si un objet source fait référence à un objet cible, il n’y a aucune garantie que l’objet cible ait également une relation avec l’objet source. Ceci est différent d’une base de données relationnelle, dans laquelle les relations sont définies par des clés étrangères et des requêtes telles que la requête inverse existe toujours.
En JPA, une relation ManyToOne
est spécifiée par l’annotation @ManyToOne
ou l’élément <many-to-one>
. Une annotation @ManyToOne
est généralement accompagnée d’une annotation @JoinColumn
. L’annotation @JoinColumn
spécifie comment la relation doit être mappée (exprimée dans) la base de données. L’annotation @JoinColumn
définit le nom de la colonne de clé étrangère (@JoinColumn(name = "...")
) dans l’objet source qui doit être utilisée pour trouver (joindre) l’objet cible.
Si la relation inverse OneToMany
est spécifiée dans l’objet cible, alors l’annotation @OneToMany
dans l’objet cible doit contenir un attribut mappedBy
pour définir cette relation inverse.
JPA définit également une relation OneToOne
, qui est similaire à une relation ManyToOne
, sauf que la relation inverse (si elle était définie) est une relation OneToOne
. La principale différence entre une relation OneToOne
et une relation ManyToOne
dans JPA est qu’une ManyToOne
contient toujours une clé étrangère de la table de l’objet source vers la table de l’objet cible, alors qu’une relation OneToOne
la clé étrangère peut être soit dans la table de l’objet source, soit dans la table de l’objet cible.
- Exemple de relation ManyToOne base de donnéesEdit
- Exemple de relation ManyToOne annotationsEdit
- Exemple de relation ManyToOne relation XMLEdit
- Voir aussiEdit
- Problèmes courantsModification
- La clé étrangère fait également partie de la clé primaire.Editer
- La clé étrangère est également mappée en tant que clé de base.Modifier
- Erreur de contrainte lors de l’insertion.Modifier
- La valeur de la clé étrangère est nullEdit
Exemple de relation ManyToOne base de donnéesEdit
EMPLOYEE (table)
EMP_ID | FIRSTNAME | DERNIER NOM | SALAIRE | ID_MANAGER |
1 | Bob | Way | 50000 | 2 |
2 | Sarah | Smith | 75000 | null |
PHONE (table)
ID | TYPE | AREA_CODE | P_NUMBER | OWNER_ID |
1 | home | 613 | 792-0000 | 1 |
2 | travail | 613 | 896-1234 | 1 |
3 | travail | 416 | 123-4444 | 2 |
Exemple de relation ManyToOne annotationsEdit
@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; ...
Exemple de relation ManyToOne relation 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>
Voir aussiEdit
- Relations
- Cascade
- Lazy Fetching
- Entité cible
- Recherche par jointure
- Lecture par lot
- Problèmes courants
- Une à une
- Mappage d’une OneToOne à l’aide d’une table de jointure
- OneToMany
Problèmes courantsModification
La clé étrangère fait également partie de la clé primaire.Editer
Voir Clés primaires à travers les relations OneToOne.
La clé étrangère est également mappée en tant que clé de base.Modifier
Si vous utilisez le même champ dans deux mappages différents, vous devez généralement rendre l’un d’eux en lecture seule à l’aide de insertable, updatable = false
. Voir Clés étrangères cibles, colonnes de jonction de clés primaires, clés primaires en cascade.
Erreur de contrainte lors de l’insertion.Modifier
Cela se produit généralement parce que vous avez mappé incorrectement la clé étrangère dans une relation OneToOne
.Voir Clés étrangères cibles, colonnes jointes de clés primaires, clés primaires en cascade. Cela peut également se produire si votre fournisseur JPA ne prend pas en charge l’intégrité référentielle ou ne résout pas les contraintes bidirectionnelles. Dans ce cas, vous devrez peut-être soit supprimer la contrainte, soit utiliser EntityManager
flush()
pour garantir l’ordre dans lequel vos objets sont écrits.
La valeur de la clé étrangère est nullEdit
Assurez-vous de définir la valeur du OneToOne
de l’objet, si le OneToOne
fait partie d’une relation bidirectionnelle OneToMany
, assurez-vous de définir le OneToOne
de l’objet lorsque vous ajoutez un objet au OneToMany
, JPA ne gère pas les relations bidirectionnelles pour vous. Vérifiez également que vous avez défini le JoinColumn
correctement, assurez-vous que vous n’avez pas défini insertable, updateable = false
ou utilisé un PrimaryKeyJoinColumn
.