[java] 누군가 JPA와 Hibernate에서 MappingBy를 설명 할 수 있습니까?

나는 최대 절전 모드를 사용하기 때문에 일대 다 관계와 다 대일 관계를 사용해야합니다. 객체에서 양방향 관계이므로 어느 방향에서든 통과 할 수 있습니다. mappedBy권장되는 방법이지만 이해할 수 없습니다. 누군가 설명 할 수 있습니까?

  • 그것을 사용하는 것이 권장되는 방법은 무엇입니까?
  • 어떤 목적으로 해결됩니까?

내 예제를 위해 주석이있는 클래스는 다음과 같습니다.

  • Airline 많은 소유 AirlineFlights
  • 많은 사람들 AirlineFlights하나 에 속합니다 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를 소유자 / 식별 기관으로 만드는가?

이론적으로는 AirlinesFlights의 항공사가되기를 바랍니다.

여기에 이미지 설명을 입력하십시오



답변

@JoinColumn두 모델을 모두 지정하면 양방향 관계가 없습니다. 당신은 두 가지 일방적 인 관계를 가지고 있으며, 그 점에서 매우 혼란스러운 매핑이 있습니다. 두 모델 모두 IDAIRLINE 열을 “소유”한다고 말하고 있습니다. 실제로 그들 중 하나만이 실제로해야합니다! ‘정상적인’것은 측면에서 완전히 @JoinColumn벗어난 @OneToMany대신 mapBy를에 추가하는 것 @OneToMany입니다.

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

이것은 Hibernate에게 “구성을 찾기 위해 수집 한 것들에 대해 ‘airline’이라는 빈 프로퍼티를 살펴 보라고한다.”


답변

MappedBy는 관계의 키가 다른쪽에 있다는 것을 동면합니다.

즉, 2 개의 테이블을 서로 연결하더라도 해당 테이블 중 1 개만 다른 테이블에 외래 키 제약 조건을 갖습니다. MappedBy를 사용하면 제약 조건이없는 테이블에서 다른 테이블로 계속 연결할 수 있습니다.


답변

mappedby최대 절전 모드에서는이 필드를 매핑하지 않도록합니다. 이미이 필드 [name = “field”]에 의해 매핑되었습니다.
필드가 다른 엔터티에 있습니다 (name of the variable in the class not the table in the database).

그렇게하지 않으면 최대 절전 모드는이 두 관계를 동일한 관계가 아니기 때문에 매핑합니다

따라서 한면에서만 매핑을 수행하고 그 사이를 조정하도록 최대 절전 모드를 설정해야합니다.


답변

Mappingby = “다른 클래스에서 생성 된 동일한 클래스의 개체”

참고 :-매핑 기준은 하나의 테이블에 외래 키 제약 조건이 있어야하므로 한 클래스에서만 사용할 수 있습니다. 에 의해 매핑 될 수 있다면 양쪽 테이블에서 외래 키를 제거하고 외래 키없이 두 테이블 사이의 관계는 없습니다.

참고 :-다음 주석에 사용할 수 있습니다 :-1. @ OneTone 2. @ OneToMany 3. @ ManyToMany

참고 — 다음 주석에는 사용할 수 없습니다 :-1. @ ManyToOne

일대일 :-매핑의 어느 한 쪽에서 수행하지만 한 쪽에서 만 수행하십시오. 클래스가 적용되는 테이블에서 외래 키 제약 조건의 추가 열을 제거합니다.

예를 들어. 직원 객체에서 직원 객체의 매핑을 적용하면 직원 테이블의 외래 키가 제거됩니다.


답변

테이블 관계와 엔티티 관계

관계형 데이터베이스 시스템에서 one-to-many테이블 관계 는 다음과 같습니다.

<code> 일대 다 </ code> 테이블 관계

관계는 post_id자식 테이블 의 외래 키 열 (예 :)을 기반으로 합니다.

따라서 one-to-many테이블 관계 를 관리 할 때 진실의 원천이 있습니다.

이제 one-to-many이전에 보았던 테이블 관계 에 맵핑되는 양방향 엔티티 관계를 사용하는 경우 :

양방향 <code> 일대 다 </ code> 엔티티 연결

위의 다이어그램을 보면이 관계를 관리하는 두 가지 방법이 있음을 알 수 있습니다.

에서 Post엔티티, 당신은이 comments모음 :

@OneToMany(
    mappedBy = "post",
    cascade = CascadeType.ALL,
    orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();

그리고 PostComment에서 post연결은 다음과 같이 매핑됩니다.

@ManyToOne(
    fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;

외래 키 열을 나타내는 두 가지 방법이 있기 때문에 연결 상태 변경을 해당 외래 키 열 값 수정으로 변환 할 때 진실의 원인을 정의해야합니다.

매핑

mappedBy속성은@ManyToOne 측면이 외래 키 열 관리를 담당하고 컬렉션은 하위 엔터티를 가져오고 상위 엔터티 상태 변경을 하위 항목으로 계단식으로 데만 사용됩니다 (예 : 상위를 제거하면 하위 엔터티도 제거해야 함).

양방향 연관의 양쪽을 동기화

이제 mappedBy속성 을 정의하고 하위 측 @ManyToOne연결이 외래 키 열을 관리하더라도 양방향 연결의 양쪽을 동기화해야합니다.

이를 수행하는 가장 좋은 방법은 다음 두 가지 유틸리티 방법을 추가하는 것입니다.

public void addComment(PostComment comment) {
    comments.add(comment);
    comment.setPost(this);
}

public void removeComment(PostComment comment) {
    comments.remove(comment);
    comment.setPost(null);
}

addCommentremoveComment방법은 양측이 동기화되어 있는지 확인합니다. 따라서 자식 엔터티를 추가하면 자식 엔터티가 부모를 가리켜 야하며 부모 엔터티는 자식 컬렉션에 자식이 포함되어 있어야합니다.

모든 양방향 엔티티 연관 유형을 동기화하는 가장 좋은 방법에 대한 자세한 내용은 이 기사를 확인 하십시오 .


답변

ManyToOne mapping으로 시작한 다음 BiDirectional 방식으로 OneToMany 매핑을 추가했습니다. 그런 다음 OneToMany 측 (일반적으로 부모 테이블 / 클래스)에서 “mappedBy”(자식이 자식 테이블 / 클래스에 의해 매핑 됨)를 언급해야하므로 최대 절전 모드에서는 DB에 EXTRA 매핑 테이블이 생성되지 않습니다 (TableName = parent_child 등).


답변