自定义 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;

        ...

}

这不会那么糟糕,但不幸的是会导致问题...我不能再简单地通过 POSTtext/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