Spring 数据 REST:返回一对多作为多对多关系



我想用Spring Boot和Spring Data REST构建一个简单的HATEOAS API。

因此,我创建了 2 个不同的实体 A 和 B。两者之间存在多对多关系。由于该关系还需要 2 个属性,因此我添加了具有这些属性的新关系 R。

对于 API,只有 A 和 B 应该可见,R 只是内部的,没有存储库。我想用一个指向 B 集合的链接来表示 A。

应该可以创建 A、创建 B、将 A 链接到 B 或将 B 链接到 A,而无需提供和返回 R 的内部属性。

我想这是一个设计问题?

可能的解决方案:

我尝试创建自定义方法 findByR_Bid(),但我无法为此方法提供自己的 id,因此"/a/b"是不可能的,它总是"/a/search/..."。

接下来,我添加了一个带有 ResponseEntities.linkToCollection(B.class) 的自定义链接,但这将表示指向"/b"的链接,而不引用 A 自己的 id。

接下来,我在 A 中实现了一个从 R 返回 List 的方法。但此列表在内部作为属性包含在内,而不是创建链接。

位码:

@Entity
public class A {
@Id
private Long id;
@OneToMany(mappedBy = "a")
private List<R> r;
// getters
}
@Entity
public class B {
@Id
private Long id;
@OneToMany(mappedBy = "b")
private List<R> r;
// getters
}
@Entity
public class R {
@Id
private Long id;
@ManyToOne(optional = false)
private A a;
@ManyToOne(optional = false)
private B b;
// internal properties
@JsonIgnore
private String foo;
@JsonIgnore
private String bar;
// getters
}

对于 JSON 响应,我希望有这样的东西:

获取/a/1

"_links" : {
"self": {
"href": "http://localhost:8080/a/1"
},
"a": {
"href": "http://localhost:8080/a/1"
},
"bs": {
"href": "http://localhost:8080/a/1/b{?page,size,sort}",
"templated": true
}
}

这很棘手,但并非不可能!

您可以使用同一个表将 B 添加到具有多对多关系的 A(反之亦然):

@Entity
public class A {
@Id
private Long id;
@OneToMany(mappedBy = "a")
private List<R> r;
@ManyToMany
@JoinTable(name = "table_r", inverseJoinColumns = { @JoinColumn(name = "b_id") })
private list<B> b;
// getters
}

这样,您可以强制休眠对支持 R 实体的人对多关系使用相同的表。Spring Data Rest 还将这种多对多关系映射到端点,因此/a/1/bs将起作用。

但是,访问关系的额外属性仍然很棘手。(需要使用/search 终结点。

另一种解决方案是为 R(从 A+B 创建)而不是标准 id。 (实际上已经存在,因为多对多关系的支持表具有基于 a_id+b_id 的组合键) 如果为组合键创建转换器,则可以访问关系属性,如下所示:/R/23-34(A-23和B-34之间的关系)

它不是太好,但有效。

最新更新