Java JPA自动加载的惰性集合

Java JPA自动加载的惰性集合,java,hibernate,spring-mvc,jpa,Java,Hibernate,Spring Mvc,Jpa,我有两个实体,关系如下: public class Category implements Serializable { @Column(name = "caID") private Integer caID; @OneToMany(cascade=CascadeType.ALL,mappedBy="caID",fetch=FetchType.LAZY) private List<Product> productList; //...

我有两个实体,关系如下:

public class Category implements Serializable {
     @Column(name = "caID")
     private Integer caID;
     @OneToMany(cascade=CascadeType.ALL,mappedBy="caID",fetch=FetchType.LAZY)
     private List<Product> productList;
     //..... GET and SET        
}
public class Product implements Serializable {
     @Column(name = "pID")
     private Integer pID;
     @JoinColumn(name = "caID", referencedColumnName = "caID")
     @ManyToOne(optional = false, fetch = FetchType.EAGER)
     private Category caID;
     //..... GET and SET        
}
公共类类别实现可序列化{
@列(name=“caID”)
私有整数caID;
@OneToMany(cascade=CascadeType.ALL,mappedBy=“caID”,fetch=FetchType.LAZY)
私有列表产品列表;
//……准备好
}
公共类产品实现可序列化{
@列(name=“pID”)
私有整数pID;
@JoinColumn(name=“caID”,referencedColumnName=“caID”)
@ManyToOne(可选=false,fetch=FetchType.EAGER)
私人类别caID;
//……准备好
}
类别模型:

private List<Category> findCategoryEntities(boolean all, int maxResults, int firstResult) {
    EntityManagerFactory eMF = null;
    EntityManager eM = null;
    try {
        eMF = getEntityManagerFactory();
        eM = getEntityManager(eMF);
        Query q=eM.createQuery("SELECT ca FROM Category ca");
        //Or using Criteria
        //CriteriaQuery cq = eM.getCriteriaBuilder().createQuery();
        //cq.select(cq.from(Category.class));
        //Query q = eM.createQuery(cq);
        if (!all) {
            q.setMaxResults(maxResults);
            q.setFirstResult(firstResult);
        }
        return q.getResultList();
    } finally {
        closeConnection(eM, eMF);
    }
}
私有列表findCategoryEntities(布尔all、int-maxResults、int-firstResult){
EntityManagerFactory eMF=null;
EntityManager eM=null;
试一试{
eMF=getEntityManagerFactory();
eM=getEntityManager(eMF);
Query q=eM.createQuery(“从类别ca中选择ca”);
//或使用标准
//CriteriaQuery cq=eM.getCriteriaBuilder().createQuery();
//cq.select(cq.from(Category.class));
//查询q=eM.createQuery(cq);
如果(!全部){
q、 setMaxResults(maxResults);
q、 setFirstResult(firstResult);
}
返回q.getResultList();
}最后{
闭合连接(eM、eMF);
}
}

我认为,若我将listProduct的获取加载设置为惰性类型,则实体管理器不会自动加载此属性。但当我调用方法“findCategoryEntities”并检查productList时,它不是null吗?在我使用标准之后,我仍然得到相同的结果。如何获取所有类别但不自动初始化productList?在这之后,我如何设置productList而不再次初始化类别?

当您将一个子项标记为lazy并加载父项时,子项列表将永远不会为空。它将使您返回到子对象列表的代理。因此,当您执行getProductList时,它将调用代理上的get,这将最终加载您的孩子

使用您的配置,当您获取所有类别时productList不会加载,请放心,它将仅在您访问getProductList时加载

[更新]
您可以按照url阅读“Hibernate中延迟加载的工作原理”一节。这可能有助于澄清延迟加载。如果您在关闭hibernate会话后访问延迟加载的元素(在该会话中加载了该元素),那么最终将出现LazyInitializationException

很抱歉,我使用PersistenceUtil的方法“isFieldLoaded”(返回true)或使用getSize()(大于0)检查了productList,但未选中等于null:DIf I use CRITIES和close EntityManagerFactory productList将自动加载。为什么?您可以按照url阅读“Hibernate中惰性加载的工作原理”一节。这可能有助于澄清延迟加载。如果在关闭hibernate会话后访问延迟加载的元素,那么将以LazyInitializationException结束