Java Persistence API 및 Hibernate의 초보자입니다.
차이 무엇 FetchType.LAZY
과 FetchType.EAGER
자바 퍼시스턴스 API 인은?
답변
때로는 두 개의 엔티티가 있고 그들 사이에 관계가 있습니다. 예를 들어,이라는 엔터티 University
와 라는 다른 엔터티가 Student
있고 대학교에는 많은 학생이있을 수 있습니다.
대학교 단체는 아이디, 이름, 주소 등과 같은 몇 가지 기본 속성과 특정 대학교의 학생 목록을 반환하는 학생이라는 수집 속성을 가질 수 있습니다.
public class University {
private String id;
private String name;
private String address;
private List<Student> students;
// setters and getters
}
이제 데이터베이스에서 University를로드하면 JPA가 해당 ID, 이름 및 주소 필드를로드합니다. 그러나 학생들을 어떻게로드해야하는지에 대한 두 가지 옵션이 있습니다.
- 나머지 필드와 함께 (즉, 간절히)로드하거나
- 대학의
getStudents()
방법 을 호출 할 때 필요에 따라 (즉, 게으르게)로드합니다 .
대학에 많은 학생이있을 경우, 특히 필요하지 않을 때 모든 학생을 함께 불러오는 것이 비효율적이며, 그러한 경우 학생이 실제로 필요할 때 학생들을 불러 들이기를 원한다고 선언 할 수 있습니다. 이것을 게으른 로딩이라고합니다.
다음 students
은 간절히로드되도록 명시 적으로 표시된 예입니다 .
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.EAGER)
private List<Student> students;
// etc.
}
다음 students
은 명시 적으로 게으르게로드되도록 표시된 예제 입니다.
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.LAZY)
private List<Student> students;
// etc.
}
답변
원래,
LAZY = fetch when needed
EAGER = fetch immediately
답변
EAGER
컬렉션을로드한다는 것은 부모를 가져올 때 완전히 가져 오는 것을 의미합니다. 당신이 가지고 Course
있고 그것을 가지고 있다면 List<Student>
, 모든 학생들은 데이터베이스 를 가져올 때 데이터베이스 에서 Course
가져옵니다.
LAZY
반면 List
에는 액세스하려는 경우에만 의 내용을 가져옵니다. 예를 들어을 호출하여 course.getStudents().iterator()
. 에서 액세스 방법을 List
호출하면 요소를 검색하기 위해 데이터베이스에 대한 호출이 시작됩니다. 이것은 List
(또는 Set
) 주위에 프록시를 생성하여 구현됩니다 . 당신의 게으른 모음 그래서, 구체적인 유형은하지 ArrayList
와 HashSet
있지만, PersistentSet
및 PersistentList
(또는 PersistentBag
)
답변
성능 및 메모리 사용률을 고려할 수 있습니다. 한 가지 큰 차이점은 EAGER 페치 전략으로 세션없이 페치 된 데이터 오브젝트를 사용할 수 있다는 것입니다. 왜?
세션이 연결될 때 오브젝트에 표시된 데이터를 열망하면 모든 데이터가 페치됩니다. 그러나 지연로드 전략의 경우, 세션이 연결 해제 된 경우 ( session.close()
명령문 이후 ) 지연로드 표시 오브젝트는 데이터를 검색하지 않습니다 . 최대 절전 모드 프록시로 만들 수있는 모든 것. Eager 전략을 사용하면 세션을 닫은 후에도 데이터를 계속 사용할 수 있습니다.
답변
내 지식에 따라 두 가지 유형의 가져 오기가 요구 사항에 따라 다릅니다.
FetchType.LAZY
요청시 (즉, 데이터가 필요할 때)
FetchType.EAGER
(즉, 요구 사항이 나오기 전에 불필요하게 레코드를 가져옵니다)
답변
기본적으로 모든 콜렉션 및 맵 오브젝트의 페치 규칙은 FetchType.LAZY
다른 규칙의 경우 FetchType.EAGER
정책을 따릅니다 .
간단히, @OneToMany
그리고 @ManyToMany
관계는 implicictly 관련 객체 (수집 및지도)를 가져 오지 않고 검색 작업을에서 필드를 통해 직렬로 연결된 @OneToOne
과 @ManyToOne
사람.
답변
모두 FetchType.LAZY
와 FetchType.EAGER
정의하는 데 사용하는 기본 계획을 가져 .
불행히도 LAZY 페치에 대한 기본 페치 계획 만 대체 할 수 있습니다. EAGER 가져 오기는 유연성이 떨어지고 많은 성능 문제가 발생할 수 있습니다 .
가져 오기는 쿼리 시간 책임이므로 연결을 EAGER로 만드는 충동을 억제하는 것이 좋습니다. 따라서 모든 쿼리는 fetch 지시문을 사용 하여 현재 비즈니스 사례에 필요한 항목 만 검색해야합니다.