Spring Data Rest @EmbeddedId 不能从 Post Request 构造 [英] Spring Data Rest @EmbeddedId cannot be constructed from Post Request

查看:15
本文介绍了Spring Data Rest @EmbeddedId 不能从 Post Request 构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

代码如下:

@Entity公共类 PersonToTeam {@EmbeddedId@Getter@Setter私有 PersonToTeamId id = 新的 PersonToTeamId();@ManyToOne@Getter@Setter@JoinColumn(name = "person_id", insertable=false, updatable=false)私人 人 人;@ManyToOne@Getter@Setter@JoinColumn(name = "team_id", insertable=false, updatable=false)私人团队;@Getter@Setter@Enumerated(EnumType.STRING)私有 RoleInTeam 角色;公共枚举 RoleInTeam {管理员、会员}}@EqualsAndHashCode@Embeddable公共类 PersonToTeamId 实现了 Serializable {private static final long serialVersionUID = -8450195271351341722L;@Getter@Setter@Column(name = "person_id")私人字符串personId;@Getter@Setter@Column(name = "team_id")私人字符串 teamId;}@零件公共类 PersonToTeamIdConverter 实现 BackendIdConverter {@覆盖公共布尔支持(类分隔符){返回 delimiter.equals(PersonToTeam.class);}@覆盖公共序列化 fromRequestId(String id, Class entityType) {如果(ID!= null){PersonToTeamId ptid = new PersonToTeamId();String[] idParts = id.split("-");ptid.setPersonId(idParts[0]);ptid.setTeamId(idParts[1]);返回ptid;}返回 BackendIdConverter.DefaultIdConverter.INSTANCE.fromRequestId(id, entityType);}@覆盖public String toRequestId(Serializable id, Class entityType) {if (id instanceof PersonToTeamId) {PersonToTeamId ptid = (PersonToTeamId) id;return String.format("%s-%s", ptid.getPersonId(), ptid.getTeamId());}返回 BackendIdConverter.DefaultIdConverter.INSTANCE.toRequestId(id, entityType);}}

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

解决方案

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

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

<代码>{ID": {"personId": "foo","teamId": "酒吧"},...}

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

<代码>{ID": {"stringId": "foo","foreignKeyId": "http://localhost:8080/path/to/other/resource/1"},...}

I have a JPA entity Person and an entity Team. Both are joined by an entity PersonToTeam. This joining entity holds a many-to-one relation to Person and one to Team. It has a multi-column key consisting of the ids of the Person and the Team, which is represented by an @EmbeddedId. To convert the embedded id back and forth to the request id I have a converter. All this follows the suggestion on Spring Data REST @Idclass not recognized

The code looks like this:

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

The problem with this converter is, that the fromRequestId method gets a null as id parameter, when a post request tries to create a new personToTeam association. But there is no other information about the payload of the post. So how should an id with foreign keys to the person and the team be created then? And as a more general question: What is the right approach for dealing many-to-many associations in spring data rest?

解决方案

After running into the same issue I found a solution. Your code should be fine, except I return new PersonToTeamId() instead of the DefaultIdConverter if id is null in fromRequestId().

Assuming you are using JSON in your post request you have to wrap personId and teamId in an id object:

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

And in cases where a part of the @EmbeddedId is not a simple data type but a foreign key:

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

这篇关于Spring Data Rest @EmbeddedId 不能从 Post Request 构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆