我有一个包含联系人集合的Person类。一切正常,我得到他们的联系人列表。但是,在日志中我看到一个单独的查询来读取每个人的集合。那太糟糕了。 如何使hibernate联接以读取一个查询中的所有数据?我使用JPA。
这是人类:
@Entity
@Table(name = "tbl1")
public class PersonItem implements Serializable{
@Id
@Column(name="col1")
private String guid;
.....
@ElementCollection(targetClass = ContactItem.class,fetch=FetchType.EAGER)
@CollectionTable(name="tbl2",joinColumns=@JoinColumn(name="col2"))
private List<ContactItem> contacts;
....
}
这是联系人类
@Embeddable
@Table(name = "tbl2")
public class ContactItem implements Serializable {
@Column(name="col1")
private String guid;
@Column(name="col3")
private String info;
}
这是我获得人员名单的方式:
Query query = em.createQuery("Select p from PersonItem p WHERE p.guid IN (:guids)");
query.setParameter("guids", guids);
List<PersonItem> list=query.getResultList();
这就是我在日志中看到的内容(我在DB中有三个人):
Hibernate: select personitem0_.col1 as col1_0_, personitem0_.col4 as col2_0_, personitem0_.col2 as col3_0_, personitem0_.col3 as col4_0_ from tbl1 personitem0_ where personitem0_.col1 in (? , ? , ?)
Hibernate: select contacts0_.col2 as col1_1_0_, contacts0_.col1 as col2_1_0_, contacts0_.col3 as col3_1_0_ from tbl2 contacts0_ where contacts0_.col2=?
Hibernate: select contacts0_.col2 as col1_1_0_, contacts0_.col1 as col2_1_0_, contacts0_.col3 as col3_1_0_ from tbl2 contacts0_ where contacts0_.col2=?
Hibernate: select contacts0_.col2 as col1_1_0_, contacts0_.col1 as col2_1_0_, contacts0_.col3 as col3_1_0_ from tbl2 contacts0_ where contacts0_.col2=?
答案 0 :(得分:4)
请从更简单的映射开始。使用复数名称和列前缀。
@Entity
@Table(name = "persons")
public class Person {
@Id
@Column(name = "f_guid")
private String guid;
@OneToMany(mappedBy = "person", fetch = FetchType.EAGER)
private List<Contact> contacts;
}
@Entity
@Table(name = "contacts")
public class Contact {
@Id
@Column(name = "f_guid")
private String guid;
@Column(name = "f_info")
private String info;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fk_person")
private Person person;
}
Person
通过contacts
表格中的外键fk_person
与contacts
相关联。
更新
看起来JPQL
会覆盖默认的抓取策略。您需要明确指定提取
select p from PersonItem p left join fetch p.contacts WHERE p.guid IN (:guids)
如果您有重复项,连接原因,您可以使用distinct
select distinct p from PersonItem p left join fetch p.contacts WHERE p.guid IN (:guids)
答案 1 :(得分:1)
对你的关系尝试@Fetch。
另外我建议在这种情况下使用@OneToMany
关系
@OneToMany(mappedBy = "person", fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN) //You can use SUBSELECT as well
private List<ContactItem> contacts;
您可以阅读有关提取策略的更多信息here
- fetch-“join”=禁用延迟加载,始终加载所有集合和实体。
- fetch-“select”(默认)=延迟加载所有集合和实体。
- batch-size =“N”=获取“N”个集合或实体,不记录。
- fetch-“subselect”=将其集合分组为子选择语句。
醇>