Search code examples
javaspring-bootjpamany-to-many

i want to know why my controller give nested response


In Spirngboot, I have use JpaRepository when i get any of the record from one table its associated with another table record, in this case i got recursive data. example i have two tables(jobs and company), jobs have company field at entity, company have jobs field Set at company entity.

this is sample of my response enter image description here

Here my Jobs entity

@Entity
public class Jobs {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(unique = true)
    private String title;
    
    @ManyToOne( fetch = FetchType.LAZY)
    @JoinColumn(name = "company")
    private Company company;
..,

Company entity


@Entity
public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    
    @Column(nullable = false, unique = true)
    private String name;
    
    @Column(length = 1500)
    private String about; 

    @Column( length = 600)
    private String companyLogoLink;
    
    @OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Jobs> jobs;
..,

I have already tried out Lazy loader at annotation

I expect when i save any new jobs record. its return job and associated company record not jobs record which is associated with company. like

job{
   id:
   title:
   company: { 
       id:
       company_name:
       jobs: {
              avoid here repeated;
             }

Solution

  • When you fetch lazily, data is retrieved from the db on demand, when the getter is invoked.

    Jackson uses getters/setters by default for serialization/deserialization. When it invokes the getter, jpa retrieves the data, then it invokes the getter on the new data when serializing it, jpa retrieves more data, and so on. I am surprised you are not getting stackoverflow error here, json format cannot represent the circular references between objects, which are absolutely legal in java.

    Solutions:

    1. Use the good practices - for de/serialization use DTOs (data transfer objects), not entities (which is the bad practice).
    2. @JsonIgnore on the properties you don't need.
    3. @JsonIdentityInfo and other jackson annotations, which can deal with circular references.