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

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

我有一个 JPA 实体 Person 和一个实体 Team。两者都由实体 PersonToTeam 加入。该加入实体与个人保持多对一关系,与团队保持一对一关系。它有一个多列键,由 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 中处理多对多关联的正确方法是什么?

最佳答案

遇到同样的问题后,我找到了解决方案。您的代码应该没问题,除了如果 idnull 时我返回 new PersonToTeamId() 而不是 DefaultIdConverter fromRequestId()

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

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

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

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

关于Spring Data Rest @EmbeddedId 无法从 Post Request 构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36606251/

相关文章:

java - 有没有办法对我的 JPQL 查询尝试的 WHERE 条件进行排序?

java - 保存实体时出现 ConcurrentModificationException

java - 如何在 spring jpa 中检查日期不为空

java - 持久化实体时出现 SQLServerException - 索引超出范围

java - Spring MessageSource 多次解析/插入字符串

java - 在 spring 3/PostgreSQL 8.4.9 中从行插入中获取自动生成的键

java - 让映射器在特定条件下不映射字段

java - 为什么 Hibernate 会忽略我的 persistence.xml 中的 JPA2 标准化属性?

java - JPA - 如何在 DDL 中将字符串列设置为 varchar(max)

spring - hibernate 中带有 onetomany 注释的 org.hibernate.exception.ConstraintViolationException