[英]How to use Hibernate lazy loading and reactive streams?
我目前正在使用 Micronaut Data 構建 REST 服務。 我已經定義了兩個 JPA 實體,以雙向@OneToMany
關系和延遲加載為界。
@Entity
@Getter
@Setter
public class ScoringEntity {
@Id
private String id;
@OneToMany(mappedBy = "scoring", fetch = FetchType.LAZY)
private Set<ContributionEntity> contributions;
}
@Entity
@Getter
@Setter
public class ContributionEntity {
@Id
private String id;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId
private ScoringEntity scoring;
}
@Repository
public interface ScoringRepository extends GenericRepository<ScoringEntity, String> {
Page<ScoringEntity> findAll(Pageable pageable);
}
在控制器中,我返回一個設置為調用存儲庫的Mono
,然后執行到 DTO( Scoring
)的映射。
@Get
public Mono<Page<Scoring>> getScoring(Pageable pageable) {
return Mono.fromCallable(() -> scoringRepository.findAll(pageable))
.map(scoringEntities -> scoringEntities.map(scoringMapper::mapScoring));
}
在findAll()
方法中一切正常,但是當映射器嘗試訪問貢獻集時,事情就變糟了:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ScoringEntity.contributions, could not initialize proxy - no Session
雖然我理解為什么會發生這種情況(事務可能以存儲庫方法結束),但我找不到令人滿意的解決方案。 將關系設置為急切加載是可行的,但它會顯着降低性能(我在其他地方讀過這將是一種代碼味道,我傾向於相信)。
此外,我無法想象反應流與休眠和延遲加載不兼容。
在這種情況下,最佳做法是什么?
有幾個選項:
@Join("contributions")
注釋添加到您的存儲庫方法@EntityGraph ...
注釋添加到您的存儲庫方法@ReadOnly
或@Transactional
的方法中進行獲取和映射,以便在調用映射器時打開會話在這種情況下,擁有響應式流沒有多大意義。 只需從帶注釋的控制器返回Page
@ExecuteOn(TaskExecutors.IO)
。
將關聯映射為EAGER
通常是代碼異味。 但是,如果您遇到總是需要加載關聯的情況,您可以通過查詢更改已執行的操作。
而不是findAll
,你會打電話:
@Repository
public interface ScoringRepository extends GenericRepository<ScoringEntity, String> {
@Query("select se from ScoringEntity se left fetch join se.contributions")
Page<ScoringEntity> findScoringWithContributions(Pageable pageable);
}
此外,我無法想象反應流與休眠和延遲加載不兼容。
在這種情況下,問題是您試圖在會話關閉后延遲加載關聯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.