我有一个 JPA 实体 Person 和一个实体 Team。两者都由实体 PersonToTeam 加入。该加入实体与个人保持多对一关系,与团队保持一对一关系。它有一个多列键,由 Person 和 Team 的 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 中处理多对多关联的正确方法是什么?
最佳答案
遇到同样的问题后,我找到了解决方案。您的代码应该没问题,除了如果 id
为 null
时我返回 new PersonToTeamId()
而不是 DefaultIdConverter
fromRequestId()
。
假设您在发布请求中使用 JSON,则必须将 personId
和 teamId
包装在 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/