【发布时间】:2021-03-07 09:28:17
【问题描述】:
我正在使用基于 Spring Boot 和 Spring Data JPA 的 CRUD 存储库构建 REST API。
JSON 序列化有问题。许多实体都包含一个关系,我想在使用get 方法检索数据时限制嵌套实体的数量。
这是两个按预期工作的实体的示例:
@Entity
@Table
public class Series {
private @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Integer id;
@Column(name = "publisher_id")
private @NotEmpty @NotNull Integer publisherId;
@Column(name = "title")
private @NotEmpty @NotNull String title;
@JsonManagedReference
@OneToMany(mappedBy = "series")
private List<Subseries> subseriesList;
public void addSubseries(Subseries subseries) {
subseriesList.add(subseries);
subseries.setSeries(this);
}
}
@Entity
@Table(name = "subseries")
public class Subseries {
private @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Integer id;
@Column(name = "series_id", insertable = false, updatable = false)
private @NotEmpty @NotNull Integer seriesId;
@Column(name = "title")
private @NotEmpty @NotNull String title;
@JsonBackReference
@ManyToOne
@JoinColumn(name = "series_id", foreignKey = @ForeignKey(name = "id"))
private @NotEmpty @NotNull Series series;
}
这两个类都实现了Serializable 接口,并有它们的getter 和setter 以及空的构造函数。
这是series/10 的get 方法的输出:
{
"id": 10,
"publisherId": 100,
"title": "Title of the series",
"subseriesList": [
{
"id": 11,
"seriesId": 10,
"title": "Title of the first subseries"
},
{
"id": 12,
"seriesId": 10,
"title": "Title of the second subseries"
}
]
}
这是subseries/11的输出:
{
"id": 11,
"seriesId": 10,
"title": "Title of the first subseries"
}
到目前为止,一切都按预期工作:我需要所选系列的子系列,这就是我得到的。这个实体出现了问题,它引用了Series:
@Entity
@Table(name = "publication")
@NoArgsConstructor
public class Publication {
private @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Integer id;
@Column(name = "publisher_id")
private Integer publisherId;
@Column(name = "series_id", insertable = false, updatable = false)
private Integer seriesId;
@Column(name = "subseries_id")
private Integer subseriesId;
@Column(name = "cover_title")
private @NotEmpty @NotNull String coverTitle;
@JsonManagedReference
@ManyToOne
@JoinColumn(name = "series_id", foreignKey = @ForeignKey(name = "id"))
private Series series;
// TODO: @ManyToOne reference for Subseries
}
这个实体代表一本书,它可能属于一个系列,也可能属于该系列的一个子系列。我想获取引用的系列和子系列作为嵌套数据,但我不想获取系列的嵌套数据。这是我得到的:
{
"id": 56,
"publisherId": 100,
"seriesId": 10,
"subseriesId": 11,
"coverTitle": "Book title",
"series": {
"id": 10,
"publisherId": 100,
"title": "Title of the series",
"subseriesList": [
{
"id": 11,
"seriesId": 10,
"title": "Title of the first subseries"
},
{
"id": 12,
"seriesId": 10,
"title": "Title of the second subseries"
}
]
}
}
我不需要子系列的完整列表(另外,第二个与所选出版物无关),我不知道如何在出版物中删除它们,同时为系列保留它们.这就是我想要的:
{
"id": 56,
"publisherId": 100,
"seriesId": 10,
"subseriesId": 11,
"coverTitle": "Book title",
"series": {
"id": 10,
"publisherId": 100,
"title": "Title of the series"
}
}
这只是一个示例,但我的项目中的许多其他实体也有同样的问题。
我遇到了类似的问题here,但情况有所不同,因为它适用于主实体而不是嵌套实体。
有人建议我为 REST 服务使用单独的 POJO,但这会使代码难以维护。
我正在寻找类似@JsonIgnore 或@JsonManagedReference/@JsonBackReference 的东西,当Series 是主要实体时允许保留引用并在它是嵌套实体时丢弃引用。另一种可能的解决方案是将嵌套实体的数量限制为一个。
有什么办法吗?
【问题讨论】:
标签: java json jpa spring-data-jpa