Hibernate에서 일대일, 다 대일 및 일대 다에 대한 기본 가져 오기 유형


103

최대 절전 모드 매핑에서 기본 가져 오기 유형은 무엇입니까?

탐험 후 알게 된 것은 :

  • 일대일로 열망 합니다.
  • 일대 다의 경우 lazy 입니다.

그러나 Eclipse에서 테스트 한 후 모두에게 열망했습니다.

JPA를 사용하는지 아니면 Hibernate를 사용하는지에 따라 달라 집니까?


1
JPA 주제에 여전히 관여하는 경우-이전 버전은 현재 Hibernate 버전에서 구식이기 때문에 질문을 새로운 답변으로 업데이트했습니다.
Alexander Rühl

답변:


193

JPA를 사용하는지 Hibernate를 사용하는지에 따라 다릅니다.

로부터 JPA 2.0 스펙 의 기본값은 다음과 같습니다 :

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

그리고 최대 절전 모드에서는 모든 것이 Lazy입니다.

최신 정보:

최신 버전의 Hibernate는 위의 JPA 기본값과 일치합니다.


11
"그리고 최대 절전 모드에서는 모든 것이 게으름입니다."최근 버전에서는 분명히 변경되었습니다. 참조하십시오 아래 알렉산더 RUHL의 답변을 .
Dinei

1
Hibernate는 JPA 구현 중 하나이므로 Hibernate를 사용하면 JPA를 사용하게됩니다. :)
xenteros

이것은 인기있는 쿼리입니다. @Ashish Agarwal 답변의 마지막 줄을 업데이트 해 주시겠습니까? Hibernate에서는 지금은 Lazy가 아닙니다.
Saurabh Tiwari

최신 Hibernate 동작과 관련하여 게시물을 업데이트했습니다.
M Anouti

열망이 모든 매핑에 대한 기본 가져 오기 유형이라고 주장하는 업데이트가 있었는데, 이는 현재 5.x 및 새 6.x Hibernate 문서에서 11.3 장에 의해 반박되었으므로 편집을 취소했습니다. 또한 단일 개체를 가져올 때 전체 데이터베이스를 선택하는 것을 의미하기 때문에 자동 열성 기능을 사용하지 않는 것은 권장 사항에 위배됩니다.
Alexander Rühl

51

질문을했을 때 답변이 정확하다는 것을 알고 있습니다.하지만 사람들 (이분 저와 같은)은 여전히 ​​WildFly 10이 왜 다르게 작동하는지 궁금해하는 것을 발견하기 때문에 현재 Hibernate 5에 대한 업데이트를 제공하고 싶습니다. .x 버전 :

에서 최대 절전 모드 5.2 사용 설명서 그것은 장에서 언급되는 11.2. 가져 오기 전략 적용 :

Hibernate 권장 사항은 모든 연관을 지연으로 정적으로 표시하고 열의를 위해 동적 가져 오기 전략을 사용하는 것입니다. 이것은 불행히도 모든 일대일 및 다 대일 연결이 기본적으로 열심히 가져와야한다고 정의하는 JPA 사양과 상충됩니다 . JPA 공급자로서 Hibernate는 해당 기본값을 따릅니다.

따라서 Hibernate는 JPA에 대해 위에서 언급 한 Ashish Agarwal처럼 작동합니다.

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

( JPA 2.1 사양 참조 )


그리고 JPA impl 대신 기본 최대 절전 모드를 사용하면 동일한 방식으로 작동합니까?
jMounir

@jMounir : 글쎄, 나는 그것을 시도하지 않았지만 Hibernate가 JPA에서 정의 된 것처럼 작동한다고 말했기 때문에 Hibernate를 사용할 때 왜 다른지 모르겠습니다. 두 경우 모두 기본 전략을 재정의 할 수 있습니다.
Alexander Rühl

15

귀하의 질문에 답하기 위해 Hibernate는 JPA 표준의 구현입니다. Hibernate에는 자체적 인 작동 특성이 있지만 Hibernate 문서에 따라

기본적으로 Hibernate는 컬렉션에 대해 지연 선택 가져 오기를 사용하고 단일 값 연결에 대해 지연 프록시 가져 오기를 사용합니다. 이러한 기본값은 대부분의 응용 프로그램에서 대부분의 연결에 적합합니다.

따라서 Hibernate는 선언 한 관계 유형에 관계없이 항상 지연 가져 오기 전략을 사용하여 모든 객체를로드합니다. 일대일 또는 다 대일 관계의 단일 개체에 대해 지연 프록시 (초기화되지 않아야하지만 null이 아님)를 사용하고 액세스를 시도 할 때 값으로 수화되는 null 컬렉션을 사용합니다. .

Hibernate는 당신이를 지정하지 않는 한, 당신이 객체에 접근을 시도 할 때만이 객체들을 값으로 채우려 고 할 것임을 이해해야합니다 fetchType.EAGER.


0

단일 값 연결의 경우, 즉 일대일 및 다
대일 :- 기본 Lazy = proxy
프록시 지연로드 :-연결된 엔터티의 프록시 개체가로드됨을 의미합니다. 즉, 관련 엔터티의 프록시 개체에 대해 두 엔터티를 연결하는 ID 만로드됩니다.
예 : A와 B는 다 대일 연관이있는 두 개의 엔티티입니다. 즉 : 모든 B에 대해 여러 A가있을 수 있습니다. A의 모든 객체는 B에 대한 참조를 포함합니다
.`

public class A{
    int aid;
    //some other A parameters;
    B b;
}
public class B{
    int bid;
     //some other B parameters;
}

`
관계 A에는 열 (aid, bid, ... 엔티티 A의 다른 열)이 포함됩니다.
관계 B에는 열 (bid, ... 엔티티 B의 다른 열)이 포함됩니다.

프록시는 A를 가져올 때 B에 대해 ID 만 가져 와서 ID 만 포함하는 B의 프록시 개체에 저장하는 경우를 의미합니다. B의 프록시 객체는 최소한의 필드 만있는 B의 하위 클래스 인 프록시 클래스의 객체입니다. bid는 이미 관계 A의 일부이므로 관계 B에서 입찰을 가져 오기 위해 쿼리를 실행할 필요가 없습니다. 엔티티 B의 다른 속성은 bid 이외의 필드에 액세스 할 때만 지연로드됩니다.

컬렉션의 경우, 즉 다 대다 및 일대 다 :-
기본값 Lazy = true


또한 가져 오기 전략 (select, join 등)이 lazy를 재정의 할 수 있습니다. 즉 : lazy = 'true'이고 fetch = 'join'이면 A를 가져 오면 B 또는 B (컬렉션의 경우)도 가져옵니다. 생각해 보면 이유를 알 수 있습니다.
단일 값 연결에 대한 기본 가져 오기는 "join"입니다.
컬렉션에 대한 기본 가져 오기는 "선택"입니다. 마지막 두 줄을 확인하십시오. 나는 그것을 논리적으로 추론했다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.