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 theDefaultIdConverter
ifid
isnull
infromRequestId()
.Assuming you are using JSON in your post request you have to wrap
personId
andteamId
in anid
object:And in cases where a part of the
@EmbeddedId
is not a simple data type but a foreign key: