簡體   English   中英

如何使用 Hibernate 延遲加載和反應流?

[英]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

雖然我理解為什么會發生這種情況(事務可能以存儲庫方法結束),但我找不到令人滿意的解決方案。 將關系設置為急切加載是可行的,但它會顯着降低性能(我在其他地方讀過這將是一種代碼味道,我傾向於相信)。

此外,我無法想象反應流與休眠和延遲加載不兼容。

在這種情況下,最佳做法是什么?

有幾個選項:

  1. @Join("contributions")注釋添加到您的存儲庫方法
  2. @EntityGraph ...注釋添加到您的存儲庫方法
  3. 在一個注解@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM