Spring Data Rest @EmbeddedId 无法从 Post Request 构造

Gre*_*gor 5 spring jpa spring-data-jpa spring-data-rest

我有一个 JPA 实体Person和一个实体Team。两者都由实体PersonToTeam加入。该加入实体与Person保持多对一关系,与Team保持一对一关系。它有一个多列键,由PersonTeam的 id 组成,由 @EmbeddedId 表示。为了将嵌入的 id 来回转换为请求 id,我有一个转换器。所有这些都遵循Spring Data REST @Idclass not recognize 的建议

代码如下所示:

@Entity
public class PersonToTeam {
    @EmbeddedId
    @Getter
    @Setter
    private PersonToTeamId id = new PersonToTeamId();

    @ManyToOne
    @Getter
    @Setter
    @JoinColumn(name = "person_id", insertable=false, updatable=false)
    private Person person;

    @ManyToOne
    @Getter
    @Setter
    @JoinColumn(name = "team_id", insertable=false, updatable=false)
    private Team team;

    @Getter
    @Setter
    @Enumerated(EnumType.STRING)
    private RoleInTeam role;

    public enum RoleInTeam {
        ADMIN, MEMBER
    }
}

    @EqualsAndHashCode
    @Embeddable
    public class PersonToTeamId implements Serializable {
        private static final long serialVersionUID = -8450195271351341722L;
        @Getter
        @Setter
        @Column(name = "person_id")
        private String personId;

        @Getter
        @Setter
        @Column(name = "team_id")
        private String teamId;
    }

@Component
public class PersonToTeamIdConverter implements BackendIdConverter {

    @Override
    public boolean supports(Class<?> delimiter) {
        return delimiter.equals(PersonToTeam.class);
    }

    @Override
    public Serializable fromRequestId(String id, Class<?> entityType) {
        if (id != null) {
            PersonToTeamId ptid = new PersonToTeamId();
            String[] idParts = id.split("-");
            ptid.setPersonId(idParts[0]);
            ptid.setTeamId(idParts[1]);
            return ptid;
        }
        return BackendIdConverter.DefaultIdConverter.INSTANCE.fromRequestId(id, entityType);
    }

    @Override
    public String toRequestId(Serializable id, Class<?> entityType) {
        if (id instanceof PersonToTeamId) {
            PersonToTeamId ptid = (PersonToTeamId) id;
            return String.format("%s-%s", ptid.getPersonId(), ptid.getTeamId());
        }
        return BackendIdConverter.DefaultIdConverter.INSTANCE.toRequestId(id, entityType);
    }
}
Run Code Online (Sandbox Code Playgroud)

此转换器的问题是,当 post 请求尝试创建新的 personToTeam 关​​联时,fromRequestId 方法获取 null 作为 id 参数。但没有关于帖子有效负载的其他信息。那么应该如何创建一个带有个人和团队外键的 id 呢?作为一个更普遍的问题:在 Spring Data Rest 中处理多对多关联的正确方法是什么?

Mar*_*tin 3

遇到同样的问题后,我找到了解决方案。你的代码应该没问题,除了我返回new PersonToTeamId()而不是DefaultIdConverterif idis nullin fromRequestId()

假设您在 post 请求中使用 JSON,则必须将personId和包装teamId在一个id对象中:

{
  "id": {
    "personId": "foo",
    "teamId": "bar"
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

如果 的一部分@EmbeddedId不是简单数据类型而是外键:

{
  "id": {
    "stringId": "foo",
    "foreignKeyId": "http://localhost:8080/path/to/other/resource/1"
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)