延迟获取具有多个关系的实体:无法写入 JSON:无法延迟初始化角色集合

Lazily fetching entity with multiple relations: Could not write JSON: failed to lazily initialize a collection of role


Message Could not write JSON: failed to lazily initialize a collection of role: core.domain.Cat.catFoods, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: core.domain.Cat.catFoods, could not initialize proxy - no Session (through reference chain: web.dto.ToysDTO["toys"]->java.util.HashSet[0]->web.dto.ToyDTO["cat"]->core.domain.Cat["catFoods"])

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

我有以下实体:Toy、Cat、CatFood 和 Food。基本上猫和玩具是 1:1 关系,猫和食物是 m:n 使用 CatFood 的关系。

@NamedEntityGraphs({
        @NamedEntityGraph(name = "toyWithCat",
                attributeNodes = @NamedAttributeNode(value = "cat"))
})
@NoArgsConstructor
@AllArgsConstructor
@Data
@ToString
@EqualsAndHashCode(callSuper = true)
@Entity
public class Toy extends BaseEntity<Long> {
    String name;
    int size;

    public Toy(Long id, String name, int size) {
        this.setId(id);
        this.name = name;
        this.size = size;
    }

    @JsonBackReference(value = "cat-reference")
    @OneToOne(mappedBy = "favoriteToy")
    private Cat cat;

}
@NamedEntityGraphs({
        @NamedEntityGraph(name = "catWithToy",
                attributeNodes = @NamedAttributeNode(value = "favoriteToy")),
        @NamedEntityGraph(name = "catWithCatFoodAndFood",
                attributeNodes = @NamedAttributeNode(value = "catFoods",
                        subgraph = "catFoodWithFood"),
                subgraphs = @NamedSubgraph(name = "catFoodWithFood",
                        attributeNodes = @NamedAttributeNode(value = "food")))
})
@Entity
public class Cat extends BaseEntity<Long> {
    String name, breed;
    Integer catYears;
    @JsonManagedReference(value = "cat-reference")
    @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, orphanRemoval = true)
    @JoinColumn(name = "toy_id", referencedColumnName = "id")
    private Toy favoriteToy;

    @JsonManagedReference(value = "cat-reference")
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "cat", cascade = {CascadeType.REMOVE}, orphanRemoval = true)
    Set<CatFood> catFoods;

我正在尝试调用这个函数

public interface ToyRepository extends Repository<Toy, Long> {
    @Query("select distinct t from Toy t")
    @EntityGraph(value = "toyWithCat", type = EntityGraph.EntityGraphType.LOAD)
    List<Toy> getToysWithCat();
}

我在用玩具抓猫时使用了相同的想法,因为玩具实体没有其他关系并且它们加载没有问题

在您的 Toy class 中,您正在使用 @EqualsAndHashCode,这将在 hashCode() 实现中解决,根据 class 的所有属性计算 hashCode ].

这意味着 Toy class 中的 hashCode 方法调用了 Cat 中的 hasCode 方法。在 cat 中有一个 CatFoodsSetCat 映射,这意味着要计算 catFoodshashCode Cat 属性 参与其中。为了计算 Cat 的 hashCode,它再次开始计算 CatFoods

SethashCode

(听起来很混乱,但目前我无法更好地描述它)

由于没有活动会话,因此无法获取计算 hashCod 所需的惰性集合。这就是为什么你得到这个例外。

要点:从 @EqualsAndHashCode 计算中明确排除 LAZY 获取的属性。您可以使用 @EqualsAndHashCode.Exclude 注释这些属性,以将它们从 hashCode 计算中排除。

要查看 hashCode 计算的实现,您可以使用 IntelliJ 的 DeLombok 功能。