2012-02-02 25 views
132

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:

  • Airlineposee muchasAirlineFlights
  • MuchosAirlineFlights 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.

enter image description here

Respuesta

107

Al especificar el @JoinColumn en ambos modelos, no tiene una relación bidireccional. Tienes dos relaciones unidireccionales, y un mapeo muy confuso de eso. Le está diciendo a ambos modelos que son "dueños" de la columna IDAIRLINE. ¡Realmente solo uno de ellos debería! Lo 'normal' es tomar por completo el @JoinColumn del lado @OneToMany, y en su lugar agregar mappedBy al @OneToMany.

@OneToMany(cascade = CascadeType.ALL, mappedBy="airline") 
public Set<AirlineFlight> getAirlineFlights() { 
    return airlineFlights; 
} 

que le dice a Hibernate "Ir mirar por encima de la propiedad bean llamado 'aérea' en la que tengo una colección de encontrar la configuración."

+0

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

+7

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

+0

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

211

señales mappedBy hibernación que la clave para la relación está en el otro lado.

Esto significa que aunque vincula 2 tablas juntas, solo una de esas tablas tiene una restricción de clave externa para la otra. MappedBy te permite seguir enlazando desde la tabla que no contiene la restricción a la otra tabla.

+23

Esta debería haber sido la respuesta aceptada. – azizunsal

+2

¿Puedes aclarar un poco más? –

+1

@Kurt Du Bois, ¿por qué usaría 'mappedBy' en lugar de definir un bidireccional (con restricciones de foreign_key en cada lado)? –

6

mappedby habla por sí mismo, le dice hibernate no mapea este campo, todo está listo mapeado por este campo [name = "field"].
campo se encuentra en la otra entidad (name of the variable in the class not the table in database) ..

Si usted no hace que Hibernate asignar este respecto dos ya que no es la misma relación

por lo que necesitamos hacer para contar hibernación el mapeo en un solo lado y la coordinación entre ellos.

+0

se asignó¿Por qué es opcional? Porque sin usar mappedBy estoy obteniendo el mismo resultado, es decir, mapeo de objetos bidireccionales –

+0

no se puede usar on2many y many2one sin usar mappedBy en una de las mismas cosas para many2many tienes que usar mappedBy en un lado – Cherif

+0

no está claro! por favor puedes darme un ejemplo? –

4

mappedBy = "objeto de la entidad de la misma clase creada en otra clase”

Nota:. -Mapped por sólo se puede utilizar en una clase porque una tabla debe contener restricción de clave externa si mapeada por puedan aplicarse de ambos lados entonces quitar clave externa de ambos mesa y sin clave externa no existe una relación b/w dos mesas

Nota: -. que puede ser el uso de las anotaciones siguientes: - 1. @ OneTone 2. @ OneToMany 3. @ ManyToMany

Nota --- Puede no se utilizará 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 la restricción de clave externa en la tabla en la que se aplica la clase.

Por ej. Si aplicamos mapeado por en la clase Empleado en el objeto empleado, se eliminará la clave externa de la tabla Empleado.

0

Comenzó con el mapeo ManyToOne, luego puso el mapeo OneToMany también para el modo BiDirectional. Entonces, en OneToMany side (normalmente su tabla/clase principal), debe mencionar "mappedBy" (la asignación se realiza por y en la tabla/clase hijo), por lo que hibernate no creará una tabla de asignación EXTRA en DB (como TableName = parent_child) .

Cuestiones relacionadas