2016-06-23 2 views
1

데이터베이스 (최대 절전 모드의 JPA)에서 엔터티 Person을 선택하고 싶습니다. Person에는 두 개의 (또는 그 이상) oneToMany-Relationships가 있습니다 (예 : AddressPhone. 내가 완전히Person의 인스턴스와 AddressPhone의 모든 관련 요소를 복원 할 방법JPA - query multiple oneToMany

. 예 : 초점 사람은 두 개의 주소와 세 개의 전화를 가지고 있습니까?

은 (내가 하나의 명령으로 Person의 인스턴스를 persist 수 있습니다,하지만 난 그것을로드 할 수 있습니까?)

@Entity 
public class Person implements Serializable { 
    @Id @GeneratedValue 
    private int id; 
    private String name; 

    @OneToMany(mappedBy="person") 
    private List<Address> addresses = new ArrayList<Address>(); 

    @OneToMany(mappedBy="person") 
    private List<Phone> phones = new ArrayList<Phone>();  // plus getter and setter 
} 

@Entity 
public class Address implements Serializable { 
    @Id @GeneratedValue 
    private int id; 

    @ManyToOne 
    private Person person; 
    private String onestring;   // plus getter and setter 
} 

@Entity 
public class Phone implements Serializable { 
    @Id @GeneratedValue 
    private int id; 

    @ManyToOne 
    private Person person; 
    private String anotherstring;   // plus getter and setter 
} 

편집 : 나는 두 가지 방법이 아래에 제시했습니다. getter를 호출하여 먼저 시도하십시오.

@Stateless 
public class PersonManager { 

@PersistenceContext 
private EntityManager em; 

public Person getPerson(int id) { 
    Person person = em.find(Person .class, id); 
    person.getAddresses(); 
    person.getPhones(); 
    return person; 
} 

결과 : 두 목록은 초기화되지 않습니다.

두 번째 방법은 :

@NamedQuery(name="PersonAddressesPhones", 
    query = "SELECT p FROM Person p " + 
      "left join fetch p.addresses " + 
      "left join fetch p.phones " + 
      "WHERE p.id = :id") 

결과 : org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

+0

이것은 자주 나타나는 최대 절전 모드 관련 문제입니다. 자세한 내용은 http://stackoverflow.com/questions/17566304/multiple-fetches-with-eager-type-in-hibernate-with-jpa를 참조하십시오. – Chris

+0

불행히도 두 번째 접근 방식을 사용하려면 최대 절전 모드 문제를 해결해야합니다 (나는 그 사실을 알지 못했습니다). 가장 먼저 작동하려면 소유권을 나타 내기 위해'@ ManyToOne' 매핑에'@ JoinColumn' 주석을 정의해야한다고 생각합니다. 참조 : http://stackoverflow.com/questions/11938253/jpa-joincolumn-vs-mappedby – Nikhil

답변

0

당신은 @OneToManyfetch = FetchType.EAGER를 지정할 수 있습니다 :이 예외가 발생합니다. 사용자 ID에 find을 입력하면 Person과 관련된 모든 전화 주소 엔티티를 가져옵니다.

이것은별로 좋은 생각이 아닙니다. 필요한 경우에만 데이터를 가져 오는 것이 좋습니다. 대안 중 일부는 다음과 같습니다

  1. 은 그대로 유지 (@OneToMany를 들어, 기본 수, 유형 게으른 가져 오기) 그냥 에 게터 전화 등의 수요에 컬렉션을 작성하고 필요한 경우 (한 작동 세션은 ) 폐쇄되지 않는

  2. 당신이 사람을 가져올 것이다 (이름) 쿼리를 작성할 수 있습니다 그것의 연관된 엔티티

Here's some good info about fetching strategies

+0

첫 번째 제안 (getter 호출)을 시도했습니다. 그러나 연결이 즉시 닫히는 것 같습니다 (Wildfly 서버에서 실행 중임). 두 번째 제안을 이미 사용하고 있습니다. 그러나이 두 가지 ArrayLists 가져올 수 없습니다. 그리고 나서 hibernate는 예외를 던진다 : org.hibernate.loader.MultipleBagFetchException : 복수의 bag을 동시에 가져올 수 없다. – Marcus

+0

원래의 질문에 둘 다 코드를 게시 할 수 있겠는가? – Nikhil