JPA - 查询多个oneToMany

时间:2016-06-23 09:46:47

标签: jpa

我想从数据库中选择一个实体Person(带有Hibernate的JPA)。 Person有两个(或更多)oneToMany-Relationships,例如AddressPhone

我如何完全还原Person的实例以及AddressPhone的所有相关实体。例如。焦点人物有两个地址和三个电话?

(我可以使用一个命令persist Person的实例,但是如何加载它?)

@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

1 个答案:

答案 0 :(得分:0)

您可以在fetch = FetchType.EAGER中指定@OneToMany。 当您对个人ID进行Person时,这会获取与find相关的所有电话,地址实体。

但这不是一个好主意。最好只在需要时获取数据。一些替代方案是:

  1. 保持原样(默认情况下,对于@OneToMany,抓取类型是懒惰的)只需调用getter 根据需要随时填写馆藏(只要您的会话是有效的 没关闭)

  2. 你可以写一个(命名的)查询,用它来获取人 相关实体

  3. Here's some good info about fetching strategies