Home > Mobile >  Inifinite recursion in Spring JPA
Inifinite recursion in Spring JPA

Time:11-30

I've created 2 entities in Spring with JPA annotations:

Project:

package com.example.technologyradar.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name="native", strategy = "native")
    private Long id;

    private String name;
    @ManyToMany(mappedBy = "projects")
    private Set<Technology> assignedTechnologies = new HashSet<Technology>();
}

Technology:

package com.example.technologyradar.model;

import com.example.technologyradar.dto.constant.TechnologyStatus;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Technology {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name="native", strategy = "native")
    private Long id;

    private String name;

    @Enumerated(EnumType.STRING)
    private TechnologyStatus technologyStatus;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, targetEntity = Category.class)
    @JoinColumn(name="category_id", referencedColumnName = "id", nullable = false)
    private Category category;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, targetEntity = Coordinate.class)
    @JoinColumn(name="coordinate_id", referencedColumnName = "id", nullable = false)
    private Coordinate coordinate;

    @ManyToMany
    @JoinTable(
            name = "projects_technologies",
            joinColumns = @JoinColumn(name="technology_id"),
            inverseJoinColumns = @JoinColumn(name="project_id")
    )
    private Set<Project> projects = new HashSet<Project>();

}

My goal is to get List of projects with technologies usage list with ignoring Coordinate and Category from Technology Entity. When I perform simply findAll():

public List<Project> getProjectsWithTechnologyUsage() {
        return (List<Project>) projectRepository.findAll();
    }

then I'm obtaining famous Infinite Recursion error:

Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.util.ArrayList[0]->com.example.technologyradar.model.Project["assignedTechnologies"])]

I know that one of the solutions is to add @JsonManagedReference and @JsonBackRerefence annotations but I don't know how to do it correctly for my particular case. I would be grateful for any suggestions. Thanks!

CodePudding user response:

If you use json serialization you can

https://github.com/mikebski/jackson-circular-reference

but anyway add to Project entity

@EqualsAndHashCode(of = "id") @ToString(of = "id")

CodePudding user response:

Actually, for your scenario, you probably just want @JsonIgnore on top of Technology.projects.

Alternatively, if you sometimes want to print Technology.projects, you can use @JsonView on top of Project.technologies instead, to modify the behavior just for this one scenario where Project is the top level object to serialize.

  • Related