M.Dietz
M.Dietz

Reputation: 1000

CrudRepository, cant save entity with a composite primary key using IdClass

I have the following entity:

@Entity
@Data
@IdClass(ProjectEmployeeId.class)
public class ProjectEmployee {

  @Id
  @ManyToOne
  private Project project;

  @Id
  @ManyToOne
  private Employee employee;

  @ManyToOne
  private ProjectEmployeeRole projectEmployeeRole;
}

The id class which defines the composite primary key for the above entity:

@Data
public class ProjectEmployeeId implements Serializable {
  private Project project;

  private Employee employee;
}

Thats the repository:

public interface ProjectEmployeeRepository
        extends CrudRepository<ProjectEmployee, ProjectEmployeeId> {
}

I tried to save a projectEmployee:

projectEmployeeRepository.save(projectEmployee);

which gives me the following error:

Resolved [org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.Long' to required type 'de.employee.Employee' for property 'employee'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.Long' to required type 'de.employee.Employee' for property 'employee': no matching editors or conversion strategy found]

Im using a composite primary key for the first time, so i´m not sure how it is supposed to work. The problem probably comes from defining CrudRepository<ProjectEmployee, ProjectEmployeeId>. The second argument is supposed to represent the id. But ProjetEmployee doesnt have one primary key, instead it has two so i thought i should add the id class into the id argument which does not work. How do i save an entity with a composite primary using IdClass key with a CrudRepository?

Upvotes: 3

Views: 4483

Answers (4)

CoYoT3
CoYoT3

Reputation: 106

Changing types of attributes inside the ClassId to match the type of Id used by nested class work for me :

@Data
public class ProjectEmployeeId implements Serializable {
  private Long project;

  private Long employee;
}

Upvotes: 0

Jelle den Burger
Jelle den Burger

Reputation: 1468

I ran into this exact same edge-case error and as Omar described in his answer, I changed the referenced entity in the "IdClass" entity to a Long.

This fixed the issue.

So in the example in the question:

  • Convert Project project to Long projectId.
  • Convert Employee employee to Long employeeId.

Upvotes: 0

Omar E
Omar E

Reputation: 11

Your repository is expecting ProjectEmployeeId suppose to have an id with Long data type. What you have in your code ProjectEmployeeId with private Employee employee object and not long primitive id.

Your composite primary should include the ID from Employee and Project and not the entire entity. In this case, consider using @Embeddable and @EmbeddedId annotations instead of @IdClass.

Upvotes: 1

Similar question like this were asked here https://stackoverflow.com/a/28346375/12699765. Try to use @EmbeddedId.

Upvotes: 0

Related Questions