2016-08-24 43 views
1

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

在这一刻,我想到的唯一的东西就是使用for each循环迭代槽收集和调用该字段的getter,但它不是很有效。集合可以有1k个对象,在这种情况下,每次迭代都会触发db。

我无法改变从数据库中获取对象的方式。

代码示例。

public class TransactionData{ 

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

List<TransactionData> transactions = getTransactions(); 

回答

0

你可以做的是这样的:

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

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

但是,如果你渴望的负载,那么所有的孩子将被载入每个父母。这应该是你最好的选择。

+0

我不确定这是否是一个好的解决方案, 我只有Parents对象的集合。 – Filus1025

1

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

参见下面

@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(); 

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

参见:

顺便说一句:据我所知做最JPA提供商进行@XXXtoOne关系的渴望加载,即使你定义映射为懒惰。 JPA规范确实允许这种行为,因为延迟加载始终只是提示数据可能会或可能不会立即加载。渴望加载另一方面立即执行。

+0

非常感谢您的回复,不幸的是,我不能使用动态实体图或命名实体图,因为它会阻止我使用搜索条件,这种情况下需要从数据库中获取数据。 – Filus1025

+0

你在你的问题中没有提到这个。如果这不能回答你的问题,那么请澄清你最初的问题。除此之外,我不同意您的评论:您可以在查询中定义参数,并且/或者您甚至可以将实体图与Criteria API一起使用 – stg