JPA具有延迟加载字段的对象集合

时间:2016-08-24 05:57:45

标签: java jpa

强制在每个集合对象中初始化Lazy Loaded字段的好方法是什么?

此时我唯一想到的就是使用for each循环来迭代收集并调用该字段的getter,但它不是很有效。集合甚至可以有1k个对象,在这种情况下,每次迭代都将触发db。

我无法改变从DB获取对象的方式。

代码示例。

public class TransactionData{

@ManyToOne(fetch = FetchType.LAZY)
private CustomerData customer;
...
}

List<TransactionData> transactions = getTransactions();

2 个答案:

答案 0 :(得分:1)

您可以定义实体图来否决默认的提取类型,因为它们是在Mapping中定义的。

参见下面的示例

@Entity
@NamedEntityGraph(
    name = "Person.addresses", 
    attributeNodes = @NamedAttributeNode("addresses")
)
public class Person {
    ...
    @OneToMany(fetch = FetchType.LAZY) // default fetch type
    private List<Address> addresses;
    ...
}

在以下查询中,现在将热切地加载地址。

EntityGraph entityGraph = entityManager.getEntityGraph("Person.addresses");
TypedQuery<Person> query = entityManager.createNamedQuery("Person.findAll", Person.class);
query.setHint("javax.persistence.loadgraph", entityGraph);
List<Person> persons = query.getResultList();

通过这种方式,您可以为每个不同的用例定义特定的提取行为。

另见:

顺便说一句:afaik做大多数JPA提供程序都会执行@XXXtoOne关系的急切加载,即使你将映射定义为lazy也是如此。 JPA规范确实允许这种行为,因为延迟加载总是只是暗示数据可能会立即加载也可能不加载。渴望加载另一只手立即执行。

答案 1 :(得分:0)

你可以做的是这样的事情:

//lazily loaded
List<Child> childList = parent.getChild(); 

// this will get all the child in memory of that particular Parent
Integer childListSize = childList.size();

但是,如果你急于加载,那么将为每个父母加载所有孩子。这应该是你最好的选择。