IllegalArgumentException: expecting IdClass mapping
@IdClass
annotation is used to define the Class that contains the id. i.e. This is generally used in case defining a compound key. i.e. a key composite of more than one attribute.
If that is the case, than this is how we do. take a look at following example.. we define a class as IdClass
and use @Id
's to define varrious Ids for this
IdClass`.
Example :
@Entity
@IdClass(AssignedRoleId.class)
public class AssignedRole
{
@Id
@ManyToOne
private User userId;
@Id
@ManyToOne
private Role roleId;
private Date dateAssigned;
}
Hope this helps.
Elaborating further on @Mukul correct answer the @IdClass
should have the following properties:
- It should implement Serializable
- It should have a constructor that takes the ids (i.e. the fields associated with
@Id
) - It should override
equals
andhashCode
It's sometime useful to make this class as a static inner class of the entity, here's an example:
@Entity
@IdClass(AssignedRoleId.class)
public class AssignedRole
{
@Id
@ManyToOne
private User userId;
@Id
@ManyToOne
private Role roleId;
private Date dateAssigned;
public static class AssignedRoleId implements Serializable {
private User userId;
private Role roleId;
public AssignedRoleId() {}
public AssignedRoleId(User userId, Role roleId) {
this.userId = userId;
this.roleId = roleId;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof AssignedRole)) {
return false;
}
AssignedRole assignedRole = (AssignedRole) o;
return Objects.equals(userId, assignedRole.getUserId()) &&
Objects.equals(roleId, assignedRole.getRoleId());
}
@Override
public int hashCode() {
return Objects.hash(userId, roleId);
}
}
}