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.