延迟获取具有多个关系的实体:无法写入 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 中有一个 CatFoods
的 Set
由 Cat
映射,这意味着要计算 catFoods
的 hashCode
Cat
属性 参与其中。为了计算 Cat 的 hashCode,它再次开始计算 CatFoods
的 Set
的 hashCode
(听起来很混乱,但目前我无法更好地描述它)
由于没有活动会话,因此无法获取计算 hashCod 所需的惰性集合。这就是为什么你得到这个例外。
要点:从 @EqualsAndHashCode
计算中明确排除 LAZY
获取的属性。您可以使用 @EqualsAndHashCode.Exclude
注释这些属性,以将它们从 hashCode 计算中排除。
要查看 hashCode 计算的实现,您可以使用 IntelliJ 的 DeLombok 功能。
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 中有一个 CatFoods
的 Set
由 Cat
映射,这意味着要计算 catFoods
的 hashCode
Cat
属性 参与其中。为了计算 Cat 的 hashCode,它再次开始计算 CatFoods
Set
的 hashCode
(听起来很混乱,但目前我无法更好地描述它)
由于没有活动会话,因此无法获取计算 hashCod 所需的惰性集合。这就是为什么你得到这个例外。
要点:从 @EqualsAndHashCode
计算中明确排除 LAZY
获取的属性。您可以使用 @EqualsAndHashCode.Exclude
注释这些属性,以将它们从 hashCode 计算中排除。
要查看 hashCode 计算的实现,您可以使用 IntelliJ 的 DeLombok 功能。