动态获取关联的实体

时间:2016-09-21 12:45:08

标签: java json spring jpa fetch

我有3个实体

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
}

与连接表非常简单的多对多关系。此设置不起作用,因为当使用jackson到json格式序列化时,如果集合上的默认提取类型为LAZY,则它具有无限深度 EVEN (我不明白为什么!?)。 / p>

我在Repository->Service->RestController上使用Spring Boot 1.4.1标准的MySQL流。{/ p>

我在@JsonBackReferenceProjectReview.reviewer上使用了ProjectReview.project但这不是我想要的,因为有时候我想要访问相关实体,有时则不能。解释说明:

当我打电话给休息服务GET ../projects时,我想看看

[{
    "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
]

但是当我打电话给GET ../users时,我想看看

[{
    "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
]

我希望你明白。应该急切地提到顶级projectReviews,但是在第二级他们不应该 - 因为它创造了无限的深度结构。

我如何设置提取或实体以提供这种结构之王?

奖金问题 - 如果默认值为projectReviews,我们为什么在json中获取LAZY

1 个答案:

答案 0 :(得分:0)

您可以使用follwoing注释来解决无限递归问题:@JsonManagedReference和@JsonBackReference。

在User.java和Project.java中使用@JsonManagedReference进行变量&#34; projectReviews&#34;和@JsonBackReference为&#34;评论家&#34;和&#34;项目&#34;

如果您无法在projectReviews下获得审阅者和项目,请使用其他方式的注释,在projectReviews中使用@JsonManagedReference,反之亦然。