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.
I have the following entities: Toy, Cat, CatFood and Food. Basically Cat with Toy are in 1:1 relation and Cat and Food are in m:n relation using 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;
And I am trying to call this function
public interface ToyRepository extends Repository<Toy, Long> {
@Query("select distinct t from Toy t")
@EntityGraph(value = "toyWithCat", type = EntityGraph.EntityGraphType.LOAD)
List<Toy> getToysWithCat();
}
I am using the same idea on fetching cats with toys as the toy entity does not have another relation and they are loaded without a problem
In your
Toyclass you are using@EqualsAndHashCodewhich will be resolved in anhashCode()implementation calculating the hashCode based on all properties of that class.That means that the hashCode method in your
Toyclass invokes thehasCodemethod onCat. In cat there is aSetofCatFoodswhich is mapped byCatwhich means that to calculate thehashCodeofcatFoodstheCatproperty is involved. To calculate the hashCode of Cat it begins again calculating thehashCodeof theSetofCatFoods(Sounds confusing but currently I am unable to describe it better)
As there is no session active the Lazy collection can not be fetched which is required to calculate the hashCod. Thats why you get this exception.
Takeaway: explicitly exclude
LAZYfetched properties from@EqualsAndHashCodecalculation. You can annotate these properties using@EqualsAndHashCode.Excludeto exclude them from the hashCode calculation.To see implementation of the hashCode calculation you can use the DeLombok functionality of IntelliJ.