ORM 매핑에서 "소유 측"이란 무엇입니까?


128

소유 측은 정확히 무엇을 의미합니까? 일부 매핑 예 ( 일대 다, 일대일, 다 대일 )에 대한 설명은 무엇입니까 ?

다음 텍스트는 Java EE 6 문서 의 @OneToOne 설명에서 발췌 한 것입니다 . 개념 소유 측면 을 볼 수 있습니다 .

일대일 다중성을 갖는 다른 엔터티에 대한 단일 값 연결을 정의합니다. 연관된 대상 엔티티는 일반적으로 참조되는 오브젝트의 유형에서 유추 될 수 있으므로 일반적으로 연관된 대상 엔티티를 명시 적으로 지정할 필요는 없습니다. 관계가 양방향 인 경우 비 소유 측은 OneToOne 어노테이션의 mappingBy 요소를 사용하여 소유 측 의 관계 필드 또는 특성을 지정해야합니다.



5
:이 읽을 때까지 나는 잃어버린 javacodegeeks.com/2013/04/...
darga33을

2
외래 키 열이있는 DB 테이블은 소유 측으로 취급됩니다. 따라서 해당 DB 테이블을 나타내는 비즈니스 항목은 해당 관계의 소유자 (소유 측)입니다. 반드시 필요한 것은 아니지만 대부분의 경우 소유 측에 @JoinColumn 주석이 있습니다.
디아블로

답변:


202

소유 측의 개념이 필요한 이유는 무엇입니까?

양방향 관계의 소유 측면에 대한 아이디어는 관계형 데이터베이스에서 객체의 경우와 같이 양방향 관계가 없다는 사실에서 비롯됩니다. 데이터베이스에는 단방향 관계-외래 키 만 있습니다.

'소유자'라는 이름의 이유는 무엇입니까?

Hibernate에 의해 추적되는 관계의 소유 측은 데이터베이스에서 외래 키 를 소유 하는 관계의 측입니다 .

소유 측 개념이 해결하는 문제는 무엇입니까?

소유 측 선언 하지 않고 매핑 된 두 엔티티의 예를 보자 .

@Entity
@Table(name="PERSONS")
public class Person {
    @OneToMany
    private List<IdDocument>  idDocuments;
}

@Entity
@Table(name="ID_DOCUMENTS")
public class IdDocument {
    @ManyToOne
    private Person person;
}

OO 관점에서이 매핑은 하나의 양방향 관계가 아니라 두 개의 개별적인 단방향 관계를 정의합니다.

매핑은 테이블 PERSONSID_DOCUMENTS을 생성 할뿐만 아니라 세 번째 연관 테이블도 생성합니다 PERSONS_ID_DOCUMENTS.

CREATE TABLE PERSONS_ID_DOCUMENTS
(
  persons_id bigint NOT NULL,
  id_documents_id bigint NOT NULL,
  CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id),
  CONSTRAINT fk_docs FOREIGN KEY (id_documents_id) REFERENCES id_documents (id),
  CONSTRAINT pk UNIQUE (id_documents_id)
)

기본 키주의 pkID_DOCUMENTS만. 이 경우 Hibernate는 관계의 양면을 독립적으로 추적합니다. 관계에 문서를 추가 Person.idDocuments하면 연관 테이블에 레코드가 삽입됩니다 PERSON_ID_DOCUMENTS.

반면 idDocument.setPerson(person)에을 호출하면 table의 외래 키 person_id를 변경합니다 ID_DOCUMENTS. Hibernate는 하나의 양방향 객체 관계 를 구현하기 위해 데이터베이스에 두 개의 단방향 (외부 키) 관계를 생성하고 있다.

소유 측 개념이 문제를 해결하는 방법 :

우리가 원하는 것은 여러 번 테이블에 ID_DOCUMENTS대한 외래 키 PERSONS와 추가 연결 테이블입니다.

이 문제를 해결하려면 Hibernate가 relation에 대한 수정 사항 추적을 중지하도록 구성해야합니다 Person.idDocuments. 최대 절전 모드는 관계 의 다른 쪽만 추적해야하며 IdDocument.person그렇게하려면 mapBy 를 추가하십시오 .

@OneToMany(mappedBy="person")
private List<IdDocument>  idDocuments;

MappingBy 무엇을 의미합니까?

"관계의이 ​​측면에 대한 수정은 이미 IdDocument.person 관계의 다른쪽에 의해 매핑 되었으므로 별도의 테이블에서 별도로 추적 할 필요가 없습니다."

GOTCHA, 결과가 있습니까?

사용 mappedBy을 우리는 호출하면 person.getDocuments().add(document), 외래 키 ID_DOCUMENTSNOT 이 관계의 소유 / 추적 측이 없기 때문에, 새 문서에 링크!

문서를 새로운 사람에게 링크하려면 관계 document.setPerson(person)소유 측면 이므로 명시 적으로 호출해야합니다 .

MappingBy를 사용 하는 경우 데이터베이스에서 새 관계의 지속성을 트리거하기 위해 소유 측이 무엇인지 알고 관계의 올바른 측면을 업데이트하는 것은 개발자의 책임입니다.


17
내가 찾은 가장 좋은 대답은 Doctrine 'mappedBy'+ 'inversedBy'를 설명합니다.
Kurt Zhong

1
매핑 및 개념의 이유를 지정해 주셔서 감사합니다.
Mohnish

1
상황이 바뀌 었는지 모르겠지만, Hibernate 5.0.9 person.getDocuments().add(document)에서 ID_DOCUMENTS. "만 호출 하면"최대 절전 모드에서 외래 키가 업데이트됩니다 .
K.Nicholas

1
@Karl Nicholas, 안녕하세요. @OneToMany이 경우 PERSIST로 설정할 수있는 주석에 계단식 속성 이 있습니다. 최대 절전 모드에서는 연결된 모든 엔터티가 DB에 저장됩니다. 누구든지 이것을 명확히 할 수 있습니까? 저자가 왜 최대 절전 모드가 비 소유 측의 변경 사항을 추적하지 않지만 실제로 최대 절전 모드가 추적을 수행한다고 말합니다.
Oleksandr Papchenko

3
캐스케이드는 상위 엔티티가 소유하지 않은 경우에도 제공자에게 하위 엔티티를 저장하도록 지시하므로 규칙을 효과적으로 수정합니다. mapBy = child.field를 갖고 있거나 캐스케이드가없는 경우 목록의 하위는 저장되지 않습니다. 또한 매핑하지 않았고 계단식이없는 경우 부모는 관계를 소유하고 새 자녀를 목록에 넣고 부모를 저장하면 새 자녀 ID를 사용할 수 없으므로 예외가 발생합니다. 조인 테이블에 저장됩니다. 일을 명확히하는 희망 ... :)
K.Nicholas

142

소유 측 이 다른 쪽을 참조하는 엔티티라고 상상할 수 있습니다 . 발췌문에서는 일대일 관계입니다. 대칭 관계 이기 때문에 객체 A가 객체 B와 관련이 있고 그 반대의 경우도 마찬가지입니다.

이는 객체 A에 객체 B에 대한 참조를 저장하고 객체 B에 객체 A에 대한 참조를 저장하는 것이 중복됨을 의미합니다. 따라서 객체를 참조하는 다른 객체를 "소유하는"객체를 선택합니다.

일대 다 관계가있는 경우 "다수"부분과 관련된 개체는 소유 측이되며, 그렇지 않으면 단일 개체에서 여러 개체에 대한 많은 참조를 저장해야합니다. 이를 피하기 위해 두 번째 클래스의 모든 객체는 참조하는 단일 객체에 대한 포인터를 갖습니다 (따라서 소유 측이됩니다).

다 대 다 관계의 경우 어쨌든 별도의 매핑 테이블이 필요하므로 소유 측면이 없습니다.

결론적으로 소유 측은 다른 쪽을 참조하는 실체입니다.


6
설명해 주셔서 감사합니다.
단지 학습자

2
'mappedBy'와 'owning side'라는 이름으로 인해 내 대답을 보는 것이 도움이 될 수 있습니다. GOTCHAs 소유 측을 정의하지 않으면 어떻게됩니까
Angular University

5
글쎄, 대답은 대부분 내가 맞다고 생각합니다. 그러나 최대 절전 모드의 경우 다 대다 관계조차도 소유 측면이 있습니다. 예를 들어 업데이트 동작에 영향을 미칩니다. 이 튜토리얼의 섹션 4 ( "Hibernate 모델 클래스 업데이트")를 자세히 살펴보십시오 : viralpatel.net/blogs/…
Pfiver

11
이 답변은 도움이되는 것보다 더 혼란 스럽습니다. 양방향 관계에있을 때 "소유 측이 다른 쪽을 참조하는 엔티티라고 상상할 수있다"고 말하면 무엇이 좋을까요? 또한 다 대다 관계의 경우 어쨌든 별도의 매핑 테이블이 필요하기 때문에 소유 측이 없습니다. @ManyToMany관계는 소유 측도 있습니다. 마찬가지로 @OneToMany관계는 조인 테이블을 사용할 수 있으며 여전히 소유 측을 지정해야합니다.
DavidS

5
기본적으로 이것은 사실보다 이해하기 쉽기 때문에 귀여워하는 귀엽고 기분 좋은 대답입니다.
DavidS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.