2013-07-15 64 views
1

以下代碼觸發Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.model.entity.WorkflowProcessEntity.workstations, no session or session was closed錯誤。所以我把這個方法用@Transactional包裝在一個服務類中,它仍然會拋出錯誤。未能在交易中延遲初始化集合

WorkstationService workstationService = (WorkstationService) ApplicationContextProvider.getApplicationContext().getBean("workstationService"); 
    for (WorkstationEntity workstationEntity : workstationService.getWorkstations(getEntity())) { 
     registerWorkstation(new ImpositionWorkstation(workstationEntity)); 
    } 

WorkstationService.java

@Transactional(readOnly = true) 
public Collection<WorkstationEntity> getWorkstations(WorkflowProcessEntity workflowProcessEntity) { 
    return workflowProcessEntity.getWorkstations(); 
} 

WorkflowProcessEntity.java

@OneToMany(mappedBy = "workflowProcess") 
@JsonIgnore 
public Collection<WorkstationEntity> getWorkstations() { 
    return workstations; 
} 

我怎樣才能正確地查詢這個關係?

+0

發佈異常的完整堆棧跟蹤以及相關代碼。 –

+0

相關代碼如上...它試圖加載getWorkstations()關係。 – Webnet

+1

堆棧跟蹤是? –

回答

5

你的代碼有兩個問題。

首先,您將分離的實體傳遞給事務服務,並期望實體自動附加。情況並非如此,分離的實體是分離的,無論你是否在事務中,試圖從分離的實體加載一些懶惰屬性將導致異常。要加載它,你必須從會話中重新加載實體,然後從這個連接的實體加載延遲集合。

其次,你假設從實體獲取集合加載它。情況並非如此。該集合被實現爲延遲加載的代理,獲取集合並返回它只不過是獲取代理(單元化)並返回它。只有在集合上調用一個方法時,代理纔會自行初始化。例如,在迭代集合時。這是在交易之外完成的。堆棧跟蹤,如果您提供了它,可能會確認異常io不是從服務內部拋出,而是從迭代中拋出服務之外。

+0

您能否詳細說明是什麼讓一個實體分離? – Webnet

+0

一旦加載實體的會話關閉(在一個典型的Spring應用程序中,當事務結束時會發生這種情況,除非您有一個開放式視圖過濾器),實體就會分離。 –

+0

感謝您的反饋......您對堆棧跟蹤信息很正確。雖然我不清楚如何構建我的代碼來解決問題。 Spring/Java應用程序在需要查詢它的關係時重新提取實體是否很常見? – Webnet