Je suis nouveau pour hiberner et dois utiliser des relations un à plusieurs et plusieurs à un. C'est une relation bidirectionnelle dans mes objets, ce qui me permet de traverser dans les deux sens. mappedBy
est la méthode recommandée, mais je ne pouvais pas le comprendre. Quelqu'un peut-il expliquer:
Par souci d’exemple, voici mes cours avec des annotations:
Airline
PROPRE de nombreux AirlineFlights
AirlineFlights
appartiennent àUNAirline
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;
}
}
AirlineFlights:
@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);
}
}
MODIFIER:
Schéma de base de données:
AirlineFlights a l'idAirline en tant que ForeignKey et Airline n'a pas d'idAirlineFlights. Cela fait-il AirlineFlights en tant que propriétaire/entité d'identification?
Théoriquement, je voudrais que la compagnie aérienne devienne le propriétaire de compagnie aérienne.
En spécifiant le @JoinColumn
sur les deux modèles, vous n’avez pas de relation à double sens. Vous avez deux relations à sens unique, et une cartographie très déroutante de cela. Vous dites aux deux modèles qu'ils "possèdent" la colonne IDAIRLINE. Vraiment, un seul d'entre eux devrait réellement! La chose «normale» consiste à supprimer complètement le @JoinColumn
du côté @OneToMany
et à ajouter à la place mappedBy au @OneToMany
.
@OneToMany(cascade = CascadeType.ALL, mappedBy="airline")
public Set<AirlineFlight> getAirlineFlights() {
return airlineFlights;
}
Cela dit à Hibernate "Allez sur la propriété du haricot nommée 'compagnie aérienne' sur la chose dont j'ai une collection pour trouver la configuration."
MappedBy signale en hibernation que la clé de la relation est de l'autre côté.
Cela signifie que même si vous liez 2 tables ensemble, une seule de ces tables est soumise à une contrainte de clé étrangère. MappedBy vous permet de créer un lien depuis la table ne contenant pas la contrainte vers l'autre table.
mappedby
il parle pour lui-même, il dit à l'hibernation de ne pas mapper ce champ, il est tout prêt mappé par ce champ [name = "field"].
Le champ est dans l'autre entité (name of the variable in the class not the table in database)
..
Si vous ne le faites pas, l'hibernation mappera ces deux relations car ce n'est pas le cas la même relation
il faut donc dire à Hibernate de faire la cartographie d'un seul côté et de se coordonner entre eux.
mappedby = "objet de l'entité de la même classe créée dans une autre classe"
Remarque: -Le 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’ya pas de relation entre deux tables.
Remarque: - il peut être utilisé pour les annotations suivantes: - 1. @ OneTone 2. @ OneToMany 3. @ @TanyToMany
Note --- Il ne peut pas être utilisé pour les annotations suivantes: - 1. @ @ ManyToOne
En un à un: - Effectuez n'importe quel côté du mappage, mais seulement d'un côté . Il supprimera la colonne supplémentaire de contrainte de clé étrangère de la table sur laquelle elle est appliquée.
Pour par exemple. Si nous appliquons un mappé par dans la classe Employee sur un employé, la clé étrangère de la table Employee sera supprimée.
Vous avez commencé avec le mappage ManyToOne, puis vous avez mis le mappage OneToMany également pour la méthode bidirectionnelle . Puis, du côté OneToMany (généralement votre table/classe parent), vous devez mentionner "mappéPar" donc hibernate ne créera pas de table de mappage EXTRA dans la base de données (comme TableName = parent_child).