development

최대 절전 모드는 동시에 여러 개의 백을 가져올 수 없습니다

big-blog 2020. 2. 20. 23:30
반응형

최대 절전 모드는 동시에 여러 개의 백을 가져올 수 없습니다


Hibernate는 SessionFactory 생성 동안이 예외를 던진다 :

org.hibernate.loader.MultipleBagFetchException : 여러 백을 동시에 가져올 수 없음

이것은 내 테스트 사례입니다.

Parent.java

@Entity
public Parent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 // @IndexColumn(name="INDEX_COL") if I had this the problem solve but I retrieve more children than I have, one child is null.
 private List<Child> children;

}

Child.java

@Entity
public Child {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @ManyToOne
 private Parent parent;

}

이 문제는 어떻습니까? 어떡해?


편집하다

좋아, 내가 가진 문제는 또 다른 "부모"엔티티가 부모 안에 있다는 것입니다. 내 실제 행동은 다음과 같습니다

Parent.java

@Entity
public Parent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @ManyToOne
 private AntoherParent anotherParent;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 private List<Child> children;

}

AnotherParent.java

@Entity
public AntoherParent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 private List<AnotherChild> anotherChildren;

}

최대 절전 모드는로 두 컬렉션을 좋아하지 FetchType.EAGER않지만 이것은 버그 인 것 같습니다. 특별한 일을하지 않습니다 ...

제거 FetchType.EAGER에서 Parent또는 AnotherParent문제가 해결하지만, 실제 솔루션을 사용하는 것입니다, 그래서 나는 그것을 필요로 @LazyCollection(LazyCollectionOption.FALSE)대신 FetchType(덕분에 Bozho 솔루션에 대한).


최신 버전의 최대 절전 모드 (JPA 2.0 지원) 가이를 처리해야한다고 생각합니다. 그러나 그렇지 않으면 컬렉션 필드에 주석을 달아서 해결할 수 있습니다.

@LazyCollection(LazyCollectionOption.FALSE)

주석 에서 fetchType속성 을 제거해야 합니다 @*ToMany.

그러나 참고는 대부분의 경우이 Set<Child>보다 더 적절하다 List<Child>당신이 정말 필요 그렇게하지 않는 한, List에 대한 이동을 -Set


List유형 에서 유형으로 간단히 변경하십시오 Set.


코드에 Hibernate 고유의 @Fetch 주석을 추가하십시오.

@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
private List<Child> childs;

최대 절전 모드 버그 HHH-1718 과 관련된 문제를 해결해야합니다.


이 게시물과 다른 게시물에 설명 된 모든 단일 옵션으로 시도한 후에 수정 사항은 다음과 같습니다.

모든 XToMany 장소에서 @ XXXToMany(mappedBy="parent", fetch=FetchType.EAGER)및 중간 이후

@Fetch(value = FetchMode.SUBSELECT)

이것은 나를 위해 일했다


이를 고치려면 단순히 중첩 된 객체 Set대신 List사용하십시오.

@OneToMany
Set<Your_object> objectList;

그리고 사용하는 것을 잊지 마세요 fetch=FetchType.EAGER

작동합니다.

CollectionId목록만을 고수하고 싶다면 최대 절전 모드에 하나 이상의 개념이 있습니다 .


이러한 종류의 객체 매핑에서 Hibernate의 동작에 대한 좋은 블로그 게시물을 찾았습니다. http://blog.eyallupu.com/2010/06/hibernate-exception-simultaneously.html


부스 EAGER 목록을 JPA에 유지하고 JPA 어노테이션 @OrderColumn 중 하나 이상을 추가 할 수 있습니다 (주문할 필드 이름 포함). 특정 최대 절전 모드 주석이 필요하지 않습니다. 그러나 선택한 필드에 0부터 시작하는 값이 없으면 목록에서 빈 요소를 만들 수 있습니다.

 [...]
 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 @OrderColumn(name="orderIndex")
 private List<Child> children;
 [...]

어린이에서 orderIndex 필드를 추가해야합니다


예외가 발생하는 이유는 Hibernate가 성능에 좋지 않은 Cartesian Product를 수행하기 때문입니다.

이제 Set대신 대신을 사용하여 문제를 "수정"할 수 있지만 List, Cartesian Product가 여전히 기본 SQL 문에 표시되므로 그렇게하지 않아야합니다.

당신은에서 전환 것이 더 낫다 FetchType.EAGER에 대한 Fetchype.LAZY열망 페치가 있기 때문에 중요한 애플리케이션의 성능 문제가 발생할 수 있습니다 끔찍한 생각 .

다중 레벨 계층에서 하위 엔티티를 가져와야하는 경우이 기사에서 설명한대로 가장 안쪽의 하위 항목에서 상위 항목까지 상위 항목을 선택하는 것이 좋습니다 .


saveral collection을 사용하여 너무 복잡한 오브젝트가 EAGER fetchType을 사용하여 오브젝트를 모두 갖는 것이 좋은 생각이 아닌 경우 LAZY를 사용하는 것이 더 좋으며 콜렉션을 실제로로드해야 할 때 다음을 사용 Hibernate.initialize(parent.child)하여 데이터를 페치하십시오.


우리는 List 대신 Set시도했지만 악몽입니다. ​​두 개의 새로운 객체를 추가하면 equals ()와 hashCode ()는 두 객체 를 구별하지 못합니다! 그들은 ID가 없기 때문에.

Eclipse와 같은 일반적인 도구는 데이터베이스 테이블에서 이러한 종류의 코드를 생성합니다.

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
}

JPA / Hibernate가 어떻게 엉망이되었는지 적절히 설명하는 이 기사읽을 수도 있습니다 . 이것을 읽은 후에는 이것이 내 인생에서 ORM을 마지막으로 사용하는 것이라고 생각합니다.

또한 기본적으로 ORM이 끔찍하다고 말하는 도메인 기반 디자인 담당자를 만났습니다.


나에게 문제는 EAGER 페치 가 중첩되어 있다는 것 입니다.

한 가지 해결책은 중첩 필드를 LAZY 로 설정하고 Hibernate.initialize ()를 사용하여 중첩 필드를로드하는 것입니다.

x = session.get(ClassName.class, id);
Hibernate.initialize(x.getNestedField());

새로운 주석을 사용하여이 문제를 해결할 수 있습니다.

@XXXToXXX(targetEntity = XXXX.class, fetch = FetchType.LAZY)

실제로 페치의 기본값은 FetchType.LAZY입니다.

참고 URL : https://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags



반응형