自定义 Spring 数据 Rest @ManyToMany 关系处理
Customizing Spring Data Rest @ManyToMany relationship handling
我有一个简单的项目 运行 Spring-Data-Rest 通过 Rest API 公开一些实体,就像这个(简化,减去 Setters/Getters):
@Entity
public class Group {
@Id
@GeneratedValue
private int id;
...
}
@Entity
public class Person{
@Id
@GeneratedValue
private int id;
...
}
现在,显然每个组都可以有Persons作为成员,这可以通过@ManyToMany
很容易地解决。不幸的是(或者通常?)群组成员包含的信息不仅仅是 "is member of"。例如,它还应该包括信息 "is admin of" 或 "is hidden member of".
这自然会导致一个额外的实体...
@Entity
public class GroupMember {
@OneToOne(optional = false)
@JoinColumn(updatable = false)
private Person member;
@OneToOne(optional = false)
@JoinColumn(updatable = false)
private Group group;
private boolean admin;
private boolean hidden;
...
}
这不会那么糟糕,但不幸的是会导致问题...我不能再简单地通过 POST
将 text/uri-list
添加到组中(例如)/groups/1/members
,但我不得不通过发布到 /groupMembers/
来创建一个新的 GroupMember 实体,恕我直言,这不再那么舒服并且破坏了 Group REST 'tree' 的凝聚力。
我该如何解决这个问题并允许简单的 POST 创建一个(基本)GroupMember,并使用默认值?当然,我可以在那里放置一个新的@RepositoryRestController 来捕获对 /groups/1/members
的任何 POST 请求,但这会阻止 text/uri-list 的列表(因为它似乎不支持)。我可以定义一个新对象,例如使用人员 ID,但这会打断流程,简单地发布一个 link 列表会更好。
另一种方法是找到一种方法来映射 Hibernate @ManyToMany 本身而无需额外的实体...但我不知道这样的方法...
我认为你是对的,最好有第三个实体,GroupMember
正如你提议的那样。你不能仍然公开一个 API 端点,让你 post 到 /groups/1/members
吗?要做到这一点,您似乎需要在控制器中具有业务逻辑来解析适当的 Person(s) 并构造 GroupMember 实例。在我看来,这似乎是该业务逻辑驻留的合适位置。
如果您正在处理 spring 数据剩余并希望在自定义控制器中处理 text/uri-list
您可以使用 Resources
类型的参数传递值,如下所示:
@RequestBody Resources<Object> incoming
你通过调用incoming.getLinks()
获得uris
您可以查看 spring 数据剩余控制器作为参考 - org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController#createPropertyReference
我有一个简单的项目 运行 Spring-Data-Rest 通过 Rest API 公开一些实体,就像这个(简化,减去 Setters/Getters):
@Entity
public class Group {
@Id
@GeneratedValue
private int id;
...
}
@Entity
public class Person{
@Id
@GeneratedValue
private int id;
...
}
现在,显然每个组都可以有Persons作为成员,这可以通过@ManyToMany
很容易地解决。不幸的是(或者通常?)群组成员包含的信息不仅仅是 "is member of"。例如,它还应该包括信息 "is admin of" 或 "is hidden member of".
这自然会导致一个额外的实体...
@Entity
public class GroupMember {
@OneToOne(optional = false)
@JoinColumn(updatable = false)
private Person member;
@OneToOne(optional = false)
@JoinColumn(updatable = false)
private Group group;
private boolean admin;
private boolean hidden;
...
}
这不会那么糟糕,但不幸的是会导致问题...我不能再简单地通过 POST
将 text/uri-list
添加到组中(例如)/groups/1/members
,但我不得不通过发布到 /groupMembers/
来创建一个新的 GroupMember 实体,恕我直言,这不再那么舒服并且破坏了 Group REST 'tree' 的凝聚力。
我该如何解决这个问题并允许简单的 POST 创建一个(基本)GroupMember,并使用默认值?当然,我可以在那里放置一个新的@RepositoryRestController 来捕获对 /groups/1/members
的任何 POST 请求,但这会阻止 text/uri-list 的列表(因为它似乎不支持)。我可以定义一个新对象,例如使用人员 ID,但这会打断流程,简单地发布一个 link 列表会更好。
另一种方法是找到一种方法来映射 Hibernate @ManyToMany 本身而无需额外的实体...但我不知道这样的方法...
我认为你是对的,最好有第三个实体,GroupMember
正如你提议的那样。你不能仍然公开一个 API 端点,让你 post 到 /groups/1/members
吗?要做到这一点,您似乎需要在控制器中具有业务逻辑来解析适当的 Person(s) 并构造 GroupMember 实例。在我看来,这似乎是该业务逻辑驻留的合适位置。
如果您正在处理 spring 数据剩余并希望在自定义控制器中处理 text/uri-list
您可以使用 Resources
类型的参数传递值,如下所示:
@RequestBody Resources<Object> incoming
你通过调用incoming.getLinks()
获得uris
您可以查看 spring 数据剩余控制器作为参考 - org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController#createPropertyReference