¿Alguien puede explicar a mappedBy en hibernación?


Soy nuevo en 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 podía entenderlo. Puede alguien por favor explicarme:

  • ¿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 muchos AirlineFlights
  • Muchos AirlineFlights pertenece a UNO Airline

Línea aérea :

@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 la idAirline como ForeignKey y la aerolínea no tiene idAirlineFlights. Esto hace, AirlineFlights como el propietario / entidad de identificación ?

Teóricamente, me gustaría que la aerolínea fuera la propietaria de Vuelos aéreos.

introduzca la descripción de la imagen aquí

Author: mdeous, 2012-02-02

5 answers

Al especificar el @JoinColumn en ambos modelos no tiene una relación de dos vías. Tienes dos relaciones unidireccionales, y un mapeo muy confuso de eso. Le estás diciendo a ambos modelos que son "dueños" de la columna IDAIRLINE. Realmente solo uno de ellos en realidad debería! Lo 'normal' es quitar el @JoinColumn del lado @OneToMany completamente, 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 "Ve a ver la propiedad bean llamada 'airline' en la cosa que tengo un colección de para encontrar la configuración."

 120
Author: Affe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-24 08:03:42

MappedBy indica hibernar que la clave para la relación está en el otro lado.

Esto significa que aunque vincule 2 tablas, solo 1 de esas tablas tiene una restricción de clave foránea a la otra. mappedBy le permite seguir enlazando desde la tabla que no contiene la restricción a la otra tabla.

 232
Author: Kurt Du Bois,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 14:15:10

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

Si no haces esa hibernación mapeará esta relación de dos, ya que no es la misma relación

Así que necesitamos decirle a hibernate que haga la asignación en un solo lado y coordine entre ellos.

 11
Author: Cherif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 07:36:13

Mappedby= "objeto de entidad de la misma clase creado en otra clase"

Nota:-Mapeado por se puede utilizar solo en una clase porque una tabla debe contener restricción de clave foránea. si mapeado por se puede aplicar en ambos lados, entonces elimina la clave foránea de ambas tablas y sin clave foránea no hay relación b / n dos tablas.

Nota: - se puede utilizar 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 :- Realizar en cualquier lado de la asignación, pero realizar en un solo lado . Eliminará la columna adicional de restricción de clave externa en la tabla en la que se aplica.

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

 6
Author: ks gujjar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-18 06:51:37

Usted comenzó con muchos mapeo de uno , entonces usted puso OneToMany mapeo también para la manera BiDireccional. Luego, en el lado de OneToMany (por lo general, su tabla/clase padre), debe mencionar "mappedBy" (la asignación se realiza por y en la tabla/clase hija), por lo que hibernate no creará una tabla de asignación ADICIONAL en DB (como TableName = parent_child).

 0
Author: Akshay N. Shelke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-23 10:59:05