Je suis nouveau dans l'hibernation et j'ai besoin d'utiliser des relations un-à-plusieurs et plusieurs-à-un. C'est une relation bidirectionnelle dans mes objets, de sorte que je puisse traverser dans les deux sens. mappedBy
est la manière recommandée de s'y prendre, cependant, je ne pouvais pas la comprendre. Quelqu'un peut-il expliquer:
- quelle est la manière recommandée de l'utiliser?
- quel but résout-il?
Pour mon exemple, voici mes cours avec des annotations:
Airline
Possède de nombreuxAirlineFlights
- Beaucoup
AirlineFlights
appartiennent à ONEAirline
Compagnie aérienne :
@Entity
@Table(name="Airline")
public class Airline {
private Integer idAirline;
private String name;
private String code;
private String aliasName;
private Set<AirlineFlight> airlineFlights = new HashSet<AirlineFlight>(0);
public Airline(){}
public Airline(String name, String code, String aliasName, Set<AirlineFlight> flights) {
setName(name);
setCode(code);
setAliasName(aliasName);
setAirlineFlights(flights);
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="IDAIRLINE", nullable=false)
public Integer getIdAirline() {
return idAirline;
}
private void setIdAirline(Integer idAirline) {
this.idAirline = idAirline;
}
@Column(name="NAME", nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = DAOUtil.convertToDBString(name);
}
@Column(name="CODE", nullable=false, length=3)
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = DAOUtil.convertToDBString(code);
}
@Column(name="ALIAS", nullable=true)
public String getAliasName() {
return aliasName;
}
public void setAliasName(String aliasName) {
if(aliasName != null)
this.aliasName = DAOUtil.convertToDBString(aliasName);
}
@OneToMany(fetch=FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinColumn(name="IDAIRLINE")
public Set<AirlineFlight> getAirlineFlights() {
return airlineFlights;
}
public void setAirlineFlights(Set<AirlineFlight> flights) {
this.airlineFlights = flights;
}
}
Vols aériens:
@Entity
@Table(name="AirlineFlight")
public class AirlineFlight {
private Integer idAirlineFlight;
private Airline airline;
private String flightNumber;
public AirlineFlight(){}
public AirlineFlight(Airline airline, String flightNumber) {
setAirline(airline);
setFlightNumber(flightNumber);
}
@Id
@GeneratedValue(generator="identity")
@GenericGenerator(name="identity", strategy="identity")
@Column(name="IDAIRLINEFLIGHT", nullable=false)
public Integer getIdAirlineFlight() {
return idAirlineFlight;
}
private void setIdAirlineFlight(Integer idAirlineFlight) {
this.idAirlineFlight = idAirlineFlight;
}
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="IDAIRLINE", nullable=false)
public Airline getAirline() {
return airline;
}
public void setAirline(Airline airline) {
this.airline = airline;
}
@Column(name="FLIGHTNUMBER", nullable=false)
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
this.flightNumber = DAOUtil.convertToDBString(flightNumber);
}
}
ÉDITER:
Schéma de la base de données:
AirlineFlights a l'idAirline comme ForeignKey et Airline n'a pas d'idAirlineFlights. Cela fait, AirlineFlights en tant que propriétaire / entité d'identification?
Théoriquement, j'aimerais que la compagnie aérienne soit propriétaire de la compagnie aérienneFlights.
la source
@ManyToOne
côté, non?MappedBy signale l'hibernation que la clé de la relation se trouve de l'autre côté.
Cela signifie que même si vous liez 2 tables ensemble, seule 1 de ces tables a une contrainte de clé étrangère sur l'autre. MappedBy vous permet de créer un lien depuis la table ne contenant pas la contrainte vers l'autre table.
la source
mappedBy
plutôt que de définir un bidirectionnel (avec des contraintes Foreign_key de chaque côté)?mappedby
parle de lui-même, il dit à hibernate de ne pas mapper ce champ. il est déjà mappé par ce champ [name = "field"].le champ est dans l'autre entité
(name of the variable in the class not the table in the database)
.nous devons donc dire à hibernate de faire le mappage d'un seul côté et de coordonner entre eux.
la source
mappedBy
etinversedBy
. D' autres ORM utilisent beaucoup plus intelligentsbelongsToMany
, leshasMany
attributs.mappedby = "objet d'entité de même classe créé dans une autre classe"
Remarque: -Mappé par ne peut être utilisé que dans une classe car une table doit contenir une contrainte de clé étrangère. si mappé par peut être appliqué des deux côtés, il supprime la clé étrangère des deux tables et sans clé étrangère, il n'y a pas de relation entre deux tables.
Remarque: - il peut être utilisé pour les annotations suivantes: - 1. @ OneTone 2. @ OneToMany 3. @ ManyToMany
Remarque --- Il ne peut pas être utilisé pour l'annotation suivante: - 1. @ ManyToOne
Dans un à un: - Exécutez de n'importe quel côté du mappage mais exécutez d'un seul côté. Il supprimera la colonne supplémentaire de contrainte de clé étrangère sur la table sur laquelle elle est appliquée.
Pour par exemple. Si nous appliquons mappé par dans la classe Employee sur l'objet Employee, la clé étrangère de la table Employee sera supprimée.
la source
Relation de table vs relation d'entité
Dans un système de base de données relationnelle, une
one-to-many
relation de table se présente comme suit:Notez que la relation est basée sur la colonne Clé étrangère (par exemple,
post_id
) dans la table enfant.Il existe donc une seule source de vérité lorsqu'il s'agit de gérer une
one-to-many
relation de table.Maintenant, si vous prenez une relation d'entité bidirectionnelle qui correspond à la
one-to-many
relation de table que nous avons vue précédemment:Si vous regardez le diagramme ci-dessus, vous pouvez voir qu'il existe deux façons de gérer cette relation.
Dans l'
Post
entité, vous avez lacomments
collection:Et, dans le
PostComment
, l'post
association est mappée comme suit:Étant donné qu'il existe deux façons de représenter la colonne de clé étrangère, vous devez définir quelle est la source de vérité lorsqu'il s'agit de traduire le changement d'état d'association en modification de la valeur de la colonne de clé étrangère équivalente.
Mappé par
L'
mappedBy
attribut indique que le@ManyToOne
côté est en charge de la gestion de la colonne de clé étrangère, et la collection est utilisée uniquement pour récupérer les entités enfants et pour mettre en cascade les changements d'état de l'entité parente aux enfants (par exemple, la suppression du parent devrait également supprimer les entités enfants).Synchronisez les deux côtés d'une association bidirectionnelle
Désormais, même si vous avez défini l'
mappedBy
attribut et que l'@ManyToOne
association côté enfant gère la colonne de clé étrangère, vous devez toujours synchroniser les deux côtés de l'association bidirectionnelle.La meilleure façon de le faire est d'ajouter ces deux méthodes utilitaires:
Les méthodes
addComment
etremoveComment
garantissent que les deux côtés sont synchronisés. Donc, si nous ajoutons une entité enfant, l'entité enfant doit pointer vers le parent et l'entité parente doit avoir l'enfant contenu dans la collection enfant.la source
Vous avez commencé avec le mappage ManyToOne, puis vous avez également mis le mappage OneToMany pour la manière BiDirectionnelle. Ensuite, du côté OneToMany (généralement votre table / classe parent), vous devez mentionner "mappedBy" (le mappage est effectué par et dans la table / classe enfant), donc hibernate ne créera pas de table de mappage EXTRA dans DB (comme TableName = parent_child).
la source