web-dev-qa-db-ja.com

JPA LazyローディングがSpringブートで機能しない

私はたくさんグーグルしました、そして、Spring Boot(最新バージョン)がレイジーローディングが機能していないことは本当に奇妙です。以下は私のコードの一部です:

私のリソース:

 public ResponseEntity<Page<AirWaybill>> searchAirWaybill(CriteraDto criteriaDto, @PageableDefault(size = 10) Pageable pageable{
airWaybillService.searchAirWaybill(criteriaDto, pageable);
        return ResponseEntity.ok().body(result);
}

私のサービス:

@Service
@Transactional
public class AirWaybillService {

//Methods

 public Page<AirWaybill> searchAirWaybill(AirWaybillCriteriaDto searchCriteria, Pageable pageable){
    //Construct the specification
            return airWaybillRepository.findAll(spec, pageable);
   }
}

My Entity:

@Entity
@Table(name = "TRACKING_AIR_WAYBILL")
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@airWaybillId") //to fix Infinite recursion with LoadedAirWaybill class
public class AirWaybill{
//Some attributes
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FK_TRACKING_CORPORATE_BRANCH_ID")
    private CorporateBranch corporateBranch;
}

デバッグ時には、すべての遅延ロードされた属性がロードされます。下の画像を参照してください。

enter image description here

私の質問の1つは、ジャクソンがそのような行動に関与する可能性があるかどうかです。遅延読み込みを有効にするために見逃した方法はありますか?

[〜#〜]編集[〜#〜]

別の質問ですが、遅延読み込みを台無しにすることにデバッガが関与する可能性はありますか?

編集2:

仕様ビルドの場合、私は:

public static Specification<AirWaybill> isBranchAirWayBill(long id){
    return new Specification<AirWaybill>() {
        @Override
        public Predicate toPredicate(Root<AirWaybill> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            return cb.equal(root.join("corporateBranch",JoinType.LEFT).get("id"),id);
        }
    };
}
6
Houssem Badri

デバッガーを使用する場合、変数の値にアクセスしようとしています。したがって、画面上のその小さな矢印をクリックすると、問題の変数の値が(遅延して)ロードされます。

1
Sofo Gial

ほとんどの場合、サービス内でデバッグを行っているため、トランザクションがアクティブであり、遅延読み込みをトリガーできます(遅延要素で呼び出されるメソッドは、データベースからのフェッチをトリガーします)。

問題は、トランザクションの外部にいる間は遅延読み込みが発生しないことです。そして、ジャクソンはあなたのエンティティを明らかにその境界の外で解析しています。

仕様を構築するときに必要なすべての依存関係をフェッチするか、@Transactionalリソースレベル(ただし、最後の手段として試してください)。

ご存知のように、LAZYフェッチ戦略はヒントにすぎません。必須のアクションではありません。熱心な人は必須です:

LAZY戦略は、データが最初にアクセスされたときに遅延してデータをフェッチする必要があるという永続性プロバイダーランタイムへのヒントです。実装は、LAZY戦略のヒントが指定されているデータを積極的にフェッチすることが許可されています。

1
Maciej Kowalski

推測にすぎません。仕様の構築中にフェッチを強制しています。

のようなものを期待しています

static Specification<AirWaybill> buildSpec() {
    return (root, query, criteriaBuilder) -> {
       Join<AirWaybill, CorporateBranch> br = (Join) root.fetch("corporateBranch");
       return criteriaBuilder.equal(br.get("addressType"), 1);
    };
}

この場合は、root.fetchからroot.join

1
Lesiak

取得したデータは既に遅延していますが、クリックしてデバッガーからのデータを監視するときに、デバッグモードの戻り値を使用しています。

0