【问题标题】:Why hibernate entity graph fetch nested lazy collections为什么休眠实体图获取嵌套的惰性集合
【发布时间】:2019-12-07 23:57:27
【问题描述】:

我正在尝试使用实体图来触发延迟集合加载,但不幸的是实体图也会触发所有嵌套集合。我正在使用 spring-data-jpa-entity-graph 库在运行时创建实体图。

@Entity
public class Brand implements Serializable {
    @OneToMany(mappedBy = "brand", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Set<Vehicle> vehicles;
}
@Entity
public class Vehicle implements Serializable {
    @ManyToOne
    @JoinColumn(name = "brand_id")
    private Brand brand;
    @OneToMany(mappedBy = "vehicle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Set<VehiclePart> parts;
}
@Entity
public class VehiclePart implements Serializable {
    @ManyToOne
    @JoinColumn(name = "vehicle_id")
    private Vehicle vehicle;
}

带有 JPA 存储库的 Spring 服务:

public interface BrandsRepository extends EntityGraphJpaRepository<Brand, Long> {

    Page<Brand> findAll(Pagable pagable, EntityGraph entityGraph);
}
@Service
public class BrandsService {

    public List<Brand> find() {
        return repository.findAll(PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "id")), EntityGraphUtils.fromAttributePaths("vehicles")).getContent();
    }

}

在这种情况下,服务还返回每个车辆的零件集合,但我只想获取每个品牌的车辆集合的品牌列表。

我们如何触发仅在第一级加载惰性集合(仅品牌车辆 - 没有车辆零件)?

【问题讨论】:

  • 不幸的是,实体图也会触发所有嵌套的集合。这是如何表现自己的?您在哪里看到急需的收藏?
  • 您知道如何防止这种情况发生吗?由于我设置了确切触发的内容,因此我还可以以某种方式设置任何其他级别。但是,如果所有嵌套的集合也会被获取,我们需要一种方法来防止它。是否还有其他解决方案可以触发惰性集合加载而无需嵌套集合。
  • 如果您回答我提出的问题,那么也许...您在哪里看到这些急切获取的数据?
  • 我在日志中看到执行了 SQL。它们在将实体映射到 dto 之前执行。然后所有数据都在 API 的 json 中可见。它看起来像 [{vehicles: [{parts:[{},{},{}]}]},{vehicles: [{parts:[{},{},{}]}]}]

标签: spring hibernate spring-data-jpa spring-data entitygraph


【解决方案1】:

我遇到了同样的问题。在我的例子中:Spring 和 hibernate 行为正确,但我可以看到,未使用的(惰性)字段是从 sql 查询的。

当您使用这些字段时,它们将通过 sql 加载。
我正在使用 lombok 和 @EqualsAndHashCode.Exclude@ToString.Exclude 有助于防止这种情况发生。

在您的情况下:添加一个 DTO 层。不要返回实体本身。
或者使用@JsonIgnore注解忽略字段。

【讨论】:

    猜你喜欢
    • 2018-01-22
    • 2019-10-24
    • 2014-05-29
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多