我有2个实体作为Parent和Child作为OneToMany关系
@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
@IndexColumn(name = "index", base = 1)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@LazyCollection(LazyCollectionOption.EXTRA)
private List<Child> childs = new ArrayList<Child>();
// getter and setter
}
那么@LazyCollection(LazyCollectionOption.EXTRA)的使用是什么?什么时候会出现在图片中,比如哪个操作带有子列表,这将是有益的?
EXTRA = .size()和.contains()不会初始化整个集合
TRUE =在首次访问时初始化整个集合
FALSE =渴望加载
这是一个非常好的问题,所以我决定把这个答案变成一个article as well。
实际上没有理由使用@LazyCollection
。
不需要TRUE
和FALSE
值,因为使用JPA FetchType.LAZY
或FetchType.EAGER
可以获得相同的行为。
EXTRA
值在JPA中没有等价物,专为非常大的集合而设计。当您第一次访问EXTRA
懒惰集合时,集合未完全加载,因为任何JPA集合通常都是如此。
相反,使用辅助SELECT
逐个获取每个元素。这可能听起来像一个优化,但它不是因为EXTRA
懒惰的集合倾向于N+1 query issues。
请注意,这仅适用于有序集合,List
用@OrderColumn
或Map
(s)注释。对于包(例如,不保留任何特定排序的实体的常规List
),@LazyCollection( LazyCollectionOption.EXTRA )
的行为与任何其他LAZY
集合一样(该集合在第一次被访问时完全取出)。
如果你有一个非常大的集合,那么你根本不应该映射它。相反,您应该只映射@ManyToOne
端,而不是父端集合,您应该使用分页的JPQL查询。
JPQL查询更容易调整,因为您可以应用任何过滤条件,并且可以对结果集进行分页。