JPA 延迟加载在 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);
   }
}

我的实体:

@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

我的一个问题是杰克逊会参与这种行为吗?有没有我可能错过激活延迟加载的方法?

编辑

另一个问题是,调试器是否会参与破坏延迟加载?

编辑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);
        }
    };
}

答案 1

休眠会话存在于 方法中,且为 。在服务类外部传递实体是一种不好的做法,因为在离开方法后会话将关闭。另一方面,您的实体包含惰性初始化集合,一旦会话关闭,就无法提取这些集合。@Transactionalsearch

良好的做法是将实体映射到传输对象,并从服务(而不是原始实体)返回这些传输对象。


答案 2

最有可能的是,您在调试时仍在服务内部,因此当事务仍然处于活动状态并且可以触发延迟加载时(在惰性元素上调用的任何方法都会触发从数据库的提取)。

问题是在事务外部时不会发生延迟加载。杰克逊正在解析你的实体,绝对超出了一个实体的界限。

在构建规范时,您应该获取所有必需的依赖项,或者在资源级别尝试使用(但作为最后的手段尝试)。@Transactional

只是为了让你知道,懒惰的获取策略只是一个提示。不是强制性操作。急切是强制性的:

LAZY 策略是对持久性提供程序运行时的提示,即在首次访问数据时应延迟获取数据。允许实现急切地获取已指定 LAZY 策略提示的数据。


推荐