Soy nuevo para hibernar y necesito usar relaciones uno a muchos y muchos a uno. Es una relación bidireccional en mis objetos, por lo que puedo atravesar desde cualquier dirección. mappedBy
es la forma recomendada de hacerlo, sin embargo, no pude entenderlo. ¿Puede alguien explicarme por favor:¿Alguien puede explicar mappedBy in hibernate?
- ¿cuál es la manera recomendada de usarlo?
- ¿qué propósito soluciona?
Por el bien de mi ejemplo, aquí están mis clases con anotaciones:
Airline
posee muchasAirlineFlights
- 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;
}
}
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);
}
}
EDIT:
base de datos de esquema:
AirlineFlights tiene la idAirline como ForeignKey y la aerolínea no tiene idAirlineFlights. Esto hace que AirlineFlights sea el propietario/entidad identificadora.
Teóricamente, me gustaría que la aerolínea sea la propietaria de las líneas aéreas.
Estoy un poco confundido por su descripción al final sobre mappedBy. ¿Importa cómo se organizan las cosas en db? @DB: AirlineFlights tiene idAirline como clave externa. La aerolínea solo tiene idAirline como clave principal y no mantiene información sobre AirlineFlights @ DB. – brainydexter
Sí, importa. El nombre en mappedBy indica a Hibernate dónde encontrar la configuración de JoinColumn. (En el método getAirline() de AirlineFlight.) La forma en que lo asignó colocando JoinColumn en una línea aérea, le indica a la aerolínea que * es * responsable de mantener los valores en la otra tabla. Es posible decirle a una Entidad que "posee" una columna en una tabla diferente y es responsable de actualizarla. No es algo que generalmente desee hacer y puede causar problemas con el orden en que se ejecutan las sentencias SQL. – Affe
Por favor, mira la edición. En el nivel DB, la tabla airlineFlight posee idAirline como columna de clave externa. Por lo tanto, JoinColumn debe colocarse en la clase/tabla airlineFlight en el ManytoOne correspondiente, ya que posee esa columna? – brainydexter