【问题标题】:Spring Data Rest @EmbeddedId cannot be constructed from Post RequestSpring Data Rest @EmbeddedId 无法从 Post Request 构造
【发布时间】:2016-04-13 18:08:27
【问题描述】:

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

代码如下所示:

@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);
    }
}

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

【问题讨论】:

  • 为什么会有private PersonToTeamId id = new PersonToTeamId();,去掉= new PersonToTeamId();部分,看看,这将工作。
  • 这不会改变任何事情。问题是当请求发布时,使用空的可序列化 id 调用 Converter。
  • 您是否偶然找到了解决方案?我遇到了同样的问题。

标签: spring jpa spring-data-jpa spring-data-rest


【解决方案1】:

遇到同样的问题后,我找到了解决方案。你的代码应该没问题,除非我返回 new PersonToTeamId() 而不是 DefaultIdConverter 如果 idfromRequestId() 中是 null

假设您在发布请求中使用 JSON,您必须将 personIdteamId 包装在 id 对象中:

{
  "id": {
    "personId": "foo",
    "teamId": "bar"
  },
  ...
}

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

{
  "id": {
    "stringId": "foo",
    "foreignKeyId": "http://localhost:8080/path/to/other/resource/1"
  },
  ...
}

【讨论】:

  • 马丁,你救了我的命! "id": {} 的细节很重要! @Gregor,请将此答案标记为正确...
  • 这个帖子请求的 URI 是什么
  • @Taimur:你到底想知道什么?实体可以在您希望的任何 URI 中公开。
  • @Martin 我遇到了 EmbiddedId 的问题,你能看看这个问题吗
    stackoverflow.com/questions/43186824/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 2014-04-04
  • 2018-03-13
  • 2014-12-02
  • 1970-01-01
  • 2018-10-08
相关资源
最近更新 更多