Soy nuevo en hibernación y necesito usar relaciones uno a muchos y muchos a uno. Es una relación bidireccional en mis objetos, de modo que puedo atravesar desde cualquier dirección. mappedBy
es la forma recomendada de hacerlo, sin embargo, no pude entenderlo. Alguien puede explicar:
- ¿Cuál es la forma recomendada de usarlo?
- ¿Qué propósito resuelve?
Por el bien de mi ejemplo, aquí están mis clases con anotaciones:
Airline
Posee muchosAirlineFlights
- Muchos
AirlineFlights
pertenecen a UNOAirline
Aerolínea :
@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;
}
}
Vuelos aéreos:
@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);
}
}
EDITAR:
Esquema de base de datos:
AirlineFlights tiene idAirline como ForeignKey y Airline no tiene idAirlineFlights. Esto hace que AirlineFlights sea el propietario / entidad de identificación.
Teóricamente, me gustaría que la aerolínea sea la propietaria de airlineFlights.
fuente
@ManyToOne
lado, ¿verdad?MappedBy señala que hiberna que la clave de la relación está del otro lado.
Esto significa que aunque vincula 2 tablas juntas, solo 1 de esas tablas tiene una restricción de clave externa a la otra. MappedBy le permite seguir enlazando desde la tabla que no contiene la restricción a la otra tabla.
fuente
mappedBy
lugar de definir un bidireccional (con restricciones de teclas extranjeras en cada lado)?mappedby
habla por sí mismo, le dice a hibernate que no asigne este campo. ya está asignado por este campo [nombre = "campo"].campo está en la otra entidad
(name of the variable in the class not the table in the database)
..así que necesitamos decirle a hibernate que haga el mapeo solo en un lado y coordine entre ellos.
fuente
mappedBy
yinversedBy
. Otros ORM utilizan mucho más inteligentesbelongsToMany
,hasMany
los atributos.mappedby = "objeto de entidad de la misma clase creado en otra clase”
Nota: -Mapeado solo se puede usar en una clase porque una tabla debe contener una restricción de clave externa. si mapeado puede aplicarse en ambos lados, entonces elimina la clave externa de ambas tablas y sin clave externa no hay relación entre dos tablas.
Nota: - se puede usar para las siguientes anotaciones: - 1. @ OneTone 2. @ OneToMany 3. @ ManyToMany
Nota --- No se puede usar para la siguiente anotación: - 1. @ ManyToOne
En uno a uno: - Realice en cualquier lado de la asignación, pero realice en un solo lado. Eliminará la columna adicional de restricción de clave externa en la tabla en la que se aplica la clase.
Por ej. Si aplicamos mapeado en la clase Empleado en el objeto empleado, se eliminará la clave externa de la tabla Empleado.
fuente
Relación de tabla versus relación de entidad
En un sistema de base de datos relacional, una
one-to-many
relación de tabla tiene el siguiente aspecto:Tenga en cuenta que la relación se basa en la columna Clave externa (por ejemplo,
post_id
) en la tabla secundaria.Entonces, hay una sola fuente de verdad cuando se trata de administrar una
one-to-many
relación de tabla.Ahora, si toma una relación de entidad bidireccional que se asigna en la
one-to-many
relación de tabla que vimos anteriormente:Si observa el diagrama anterior, puede ver que hay dos formas de administrar esta relación.
En la
Post
entidad, tiene lacomments
colección:Y, en el
PostComment
, lapost
asociación se asigna de la siguiente manera:Debido a que hay dos formas de representar la columna Clave externa, debe definir cuál es la fuente de la verdad cuando se trata de traducir el cambio de estado de asociación en su modificación equivalente del valor de la columna Clave externa.
MappedBy
El
mappedBy
atributo indica que el@ManyToOne
lado está a cargo de administrar la columna Clave externa, y que la colección se usa solo para recuperar las entidades secundarias y en cascada los cambios de estado de la entidad primaria a los elementos secundarios (por ejemplo, eliminar el elemento primario también debería eliminar las entidades secundarias).Sincronice ambos lados de una asociación bidireccional
Ahora, incluso si definió el
mappedBy
atributo y la@ManyToOne
asociación del lado secundario maneja la columna Clave externa, aún necesita sincronizar ambos lados de la asociación bidireccional.La mejor manera de hacerlo es agregar estos dos métodos de utilidad:
Los métodos
addComment
yremoveComment
aseguran que ambos lados estén sincronizados. Entonces, si agregamos una entidad secundaria, la entidad secundaria debe apuntar al elemento primario y la entidad principal debe tener el elemento secundario contenido en la colección secundaria.fuente
Comenzó con el mapeo ManyToOne, luego colocó el mapeo OneToMany también de manera bidireccional. Luego, en el lado de OneToMany (generalmente su tabla / clase principal), debe mencionar "mappedBy" (la asignación se realiza por y en la tabla / clase secundaria), por lo que hibernate no creará una tabla de asignación EXTRA en DB (como TableName = parent_child).
fuente