2013-07-27 100 views
6

我見過幾個類似的問題,0個很好的答案。JPA渴望加載FetchType.LAZY子集合

這應該很簡單。我正在使用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只是爲了得到這個工作的權利。

+1

你是如何驗證它是牽強?是否有orm.xml或其他位置映射或實體偵聽器可能會設置爲覆蓋惰性設置或觸發集合?你在使用什麼提供商? – Chris

+0

在調試器中,我可以在查找調用後看到列表已填充。我沒有使用任何XML進行配置,只有註釋。 –

+0

現在我已經創建了一個非常臃腫和hacky的解決方案。我創建了兩個父實體,一個具有子列表集合,另一個沒有。不幸的是,這種攻擊(如許多黑客所做的那樣)級聯到我的代碼的其餘部分。 –

回答

4

我已經這樣做了。請參考這一點,就可以很好地工作overthere太:

@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; 
    } 

} 
+0

這周我有空閒時我會試試這個。謝謝。 –

+0

歡迎您! – Rajesh

+0

你能告訴你爲什麼在getMemberWithMemberDetails中使用合併嗎? – iku

2

我積極尋找答案,你的#2:讓JPA懶加載的東西有時會和熱切地等待其他時間。

至於你的第一個問題,我覺得你想要的是使用getReference()而不是find()。如果您使用的是Hibernate,那麼它會創建對象的引用,然後只在需要時才實際獲取它。

我敢肯定,這將幫助: When to use EntityManager.find() vs EntityManager.getReference()