Может кто-нибудь объяснить mappedBy в спящем режиме? - PullRequest
158 голосов
/ 02 февраля 2012

Я новичок в спящем режиме и мне нужно использовать отношения один-ко-многим и многие-к-одному.Это двунаправленные отношения в моих объектах, так что я могу перемещаться в любом направлении.mappedBy - рекомендуемый способ, но я не мог этого понять.Может кто-нибудь объяснить:

  • каков рекомендуемый способ его использования?
  • с какой целью это решается?

Ради моего примера,Вот мои уроки с аннотациями:

  • Airline СВОИМИ многие AirlineFlights
  • Многие AirlineFlights принадлежат ONE Airline

Авиакомпания :

@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;
    }
}

АвиакомпанияПолеты:

@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);
    }
}

РЕДАКТИРОВАНИЕ:

Схема базы данных:

У AirlineFlights есть idAirline, поскольку ForeignKey и у Airline нет idAirlineFlights.Это означает, что AirlineFlights является владельцем / идентифицирующим лицом?

Теоретически, я бы хотел, чтобы авиакомпания была владельцем авиакомпании Airlines.

enter image description here

Ответы [ 5 ]

266 голосов
/ 02 февраля 2012

MappedBy сигнализирует в спящем режиме, что ключ для связи находится на другой стороне.

Это означает, что, хотя вы связываете 2 таблицы вместе, только одна из этих таблиц имеет ограничение внешнего ключа для другой.MappedBy позволяет вам по-прежнему ссылаться из таблицы, не содержащей ограничения, на другую таблицу.

135 голосов
/ 02 февраля 2012

При указании @JoinColumn в обеих моделях у вас нет двусторонних отношений.У вас есть два односторонних отношения и очень запутанное отображение этого.Вы говорите обеим моделям, что они "владеют" столбцом IDAIRLINE.На самом деле только один из них должен!«Нормальная» вещь состоит в том, чтобы полностью убрать @JoinColumn со стороны @OneToMany и вместо этого добавить mappedBy к @OneToMany.

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

Это говорит Hibernate: «Иди, посмотри на бин»свойство «авиакомпания» на предмете, который у меня есть, чтобы найти конфигурацию. "

19 голосов
/ 17 сентября 2016

mappedby говорит сам за себя, он говорит Hibernate не отображать это поле. оно уже сопоставлено этим полем [name = "field"].
поле находится в другом объекте (name of the variable in the class not the table in the database) ..

Если вы этого не сделаете, Hibernate отобразит эти два отношения, поскольку это не так то же отношение

поэтому нам нужно указать hibernate сделать отображение только на одной стороне и координировать их.

10 голосов
/ 18 января 2017

mappedby = "объект сущности того же класса, созданный в другом классе"

Примечание: -Mappped может использоваться только в одном классе, потому что одна таблица должна содержать ограничение внешнего ключа. если сопоставление может быть применено к обеим сторонам, тогда он удаляет внешний ключ из обеих таблиц, и без внешнего ключа нет никакой связи между двумя таблицами.

Примечание: - его можно использовать для следующих аннотаций: - 1. @ OneTone 2. @ OneToMany 3. @ ManyToMany

Примечание --- Его нельзя использовать для следующей аннотации: - 1. @ ManyToOne

В отношении один к одному: - Выполнять на любой стороне сопоставления, но выполнять только на одной стороне. Он удалит лишний столбец ограничения внешнего ключа в таблице, к какому классу он применяется.

Например, Если мы применим отображение в классе Employee к объекту employee, внешний ключ из таблицы Employee будет удален.

0 голосов
/ 23 сентября 2017

Вы начали с сопоставления ManyToOne, затем добавили сопоставление OneToMany также для двунаправленного способа.Затем на стороне OneToMany (обычно это ваша родительская таблица / класс), вы должны упомянуть «mappedBy» (отображение выполняется и в дочерней таблице / классе), поэтому hibernate не будет создавать таблицу отображения EXTRA в БД (как TableName = parent_child).

...