简体   繁体   中英

Dynamically fetch associated entities

I have 3 entities

Project.java

@Entity
public class Project {
    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @OneToMany(mappedBy = "project", fetch = FetchType.LAZY)
    private List<ProjectReview> projectReviews = new ArrayList<>();

    // getters
}

User.java

@Entity
public class User {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String userName;

    @OneToMany(mappedBy = "reviewer")
    private List<ProjectReview> projectReviews = new ArrayList<>();

    // getters
}

ProjectReview.java

@Entity
@IdClass(ProjectRevieweId.class)
public class ProjectReview {

    @Id
    private long projectId;

    @Id
    private long userId;

    @Column(nullable = false)
    private String review;

    @ManyToOne
    @JoinColumn(name = "userId", insertable = false, updatable = false)
    private User reviewer;

    @ManyToOne
    @JoinColumn(name = "projectId", insertable = false, updatable = false)
    private Project project;

    // getters
}

Pretty simple many-to-many relationship with join table. This setup is not working, because when serialized with jackson to json format, it has infinite depth EVEN if the default fetch type is LAZY on collections (i dont understand why!?).

I am using standard Spring Repository->Service->RestController flow with Spring Boot 1.4.1 on MySQL .

I used the @JsonBackReference on ProjectReview.reviewer and ProjectReview.project but thats not what I want, because sometimes i want to have access to associated entities, and sometimes not. Explanation folllows:

When I call rest service GET ../projects, i would like to see

[{
    "id":1,
    "name":"project1",
    "projectReviews":[{
        "review":"My super review!",
        "reviewer":{ -- this has to be included
            "id":1,
            "userName":"user1",
            "projectReviews":null -- this cant be fetched as it causes recursion
            },
        "project":{ -- instance or null or entirely missing this attribute - as it is the same as root
            "id":1,
            "name":"project1",    
            "projectReviews":null -- this cant be fetched as it causes recursion        
            }
        },
        {
            -- second review...
        }]
    },{
            -- second project...
    },
    ...etc
]

But when I call GET ../users, i would like to see

[{
    "id":1,
    "userName":"user1",
    "projectReviews":[{
        "review":"My super review!",
        "reviewer":{ -- instance or null or entirely missing this attribute - as it is the same as root
            "id":1,
            "userName":"user1",
            "projectReviews":null -- this cant be fetched as it causes recursion
            },
        "project":{ -- this has to be included
            "id":1,
            "name":"project1",    
            "projectReviews":null -- this cant be fetched as it causes recursion        
            }       
        },
        {
            -- second review...       
        }]
    },{ 
        -- second user
    }
        ...etc
]

I hope you get it. projectReviews on top level should be eagerly fetched, but on second level they should not - beacuse it creates infinite depth structure.

How could I setup the fetching or entities to provide this king of structure?

Bonus question - Why are projectReviews fetched in json if default is LAZY fetching?

You can use follwoing annotations to solve the infinite recursion problem : @JsonManagedReference and @JsonBackReference.

Use @JsonManagedReference in User.java and Project.java for variable "projectReviews" and @JsonBackReference for "reviewer" and "project"

If you are not able to get reviewer and project under projectReviews, please use the annotations othey way around, @JsonManagedReference in projectReviews and vice versa.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM