JPA急于加载FetchType.LAZY子集合

时间:2013-07-27 22:14:28

标签: jpa lazy-loading

我已经看到了几个类似的问题和0个好答案。

这应该很简单。我正在使用Java JPA,我想有时加载一个子实体列表但不是所有时间。不幸的是,当我说懒惰地取出它时,JPA似乎没有听我说。我已经100%确定我的代码中没有任何地方以任何方式访问childEntities属性。但是,所有子实体仍然在我的JPA.em()。find(..)调用后立即加载。这就是我如何宣告与注释的关系。

@Entity
@Table(name = "parentEntities")
public class ParentEntity implements Serializable {
    ....
    @OneToMany(mappedBy = "entityPropertyName", fetch = FetchType.LAZY)
    public List<ChildEntity> childEntities;
    ...
}

这就是我加载父实体的方式:

ParentEntity parentEntity = JPA.em().find(ParentEntity.class, id);

此外,我希望有时候渴望获取此集合并能够动态告诉JPA何时这样做。那是第2步。第1步就是让这个工作正常。

2 个答案:

答案 0 :(得分:5)

我这样做了。请参考这个,它也将出色地工作:

@Entity
@Table(name = "member_information")
    public class MemberInformation  implements Serilizable{

     @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE},optional = false)
        private MemberInformationDetails memberInformationDetailsId;


     @LazyCollection(LazyCollectionOption.TRUE)
        @OneToMany(mappedBy = "memberInformationId", cascade = CascadeType.ALL)
        private Collection<AccountOpening> accountOpeningCollection;


    }

使用@OneToOne(fetch = FetchType.LAZY....)进行一对一映射,并使用@LazyCollection(LazyCollectionOption.TRUE)进行收集。

@Entity
@Table(name = "member_info_details")
public class MemberInformationDetails implements Serializable{

@OneToOne(mappedBy = "memberInformationDetailsId")
    private MemberInformation memberInformationId;

.......//getter and setters

}


@Entity
@Table(name = "account_opening")
public class AccountOpening  implements Serializable {

 @JoinColumn(name = "member_information_id", referencedColumnName = "id", nullable = false)
    @ManyToOne(optional = false)
    private MemberInformation memberInformationId;

..........//getters and setters

}

如果要访问集合,请先合并并获取对象:

@Stateless
public class MemberInformationFacade{
..............
  public MemberInformation getMemberWithMemberDetails(MemberInformation m) {
        m = getEntityManager().merge(m);
        try {
            m.getMemberInformationDetailsId().getId();


            m.getMemberInformationDetailsId().accountOpeningCollection().size();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return m;
    }

}

答案 1 :(得分:2)

我正在积极寻找你的#2的答案:有时候让JPA懒得加载,有时候急切地等待。

关于你的#1问题,我觉得你想要的是使用getReference()而不是find()。如果您正在使用Hibernate,那么它将创建对象的引用,然后只在需要时实际获取它。

我相信这会有所帮助: When to use EntityManager.find() vs EntityManager.getReference()