I have two entities called Appointement
and Client
, and I would like to get all the
appointements of a given client. I am struggling with the following error message when I try to do so.
2022-05-24 13:30:41.685 WARN 23252 --- [ XNIO-3 task-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [1000] did not match expected type [ma.mycom.myapp.domain.Client (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [1000] did not match expected type [ma.mycom.myapp.domain.Client (n/a)]]
Here are my entities:
Client.java
@Entity
@Table(name = "CLIENTS")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Client implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "id")
private Long id;
//other attributes, getters, setters
}
Appointment.java
@Entity
@Table(name = "APPOINTMRNTS")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Appointment implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "id")
private Long id;
//other attributes
@ManyToOne
@JoinColumn(name = "ID_CLIENT")
private Client client;
//getters, setters
}
Controller, and how I call the query:
List<Appointement> clientAppointements = appointementRepository.findAllByClient(idClient);
Here is the query used in AppointementRepository.java
(I guess it's the source of the problem)
@Query(
name = "SELECT pe.* FROM APPOINTEMENTS pe INNER JOIN CLIENTS e ON pe.ID_CLIENT = e.ID WHERE e.id = ?1",
nativeQuery = true
)
List<Appointement> findAllByClient(Long idClient);
CodePudding user response:
Your Appointment
class does not have a field called "client id" of any sort, it is only aware of the Client
entity it has.
In your JPA repository methods, you can only use the existing fields of an entity.
Two of the most standard ways you can fix this are:
1- Adding Appointment
field to the Client
side of the relationship to make it bidirectional (I recommend this personally). Your Client
entity will look like this:
@Entity
@Table(name = "CLIENTS")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Client implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "id")
private Long id;
@OneToMany(mappedBy = "client", fetch = FetchType.LAZY)
List<Appointment> appointments;
//other attributes, getters, setters
}
Then you can simply get appointments by fetching a Client
object, then simply accessing its appointments
field.
List<Appointement> clientAppointements = clientRepository.findClientByField(field)
.getAppointments();
or you can even get appointments of a client in repository methods:
// in your appointment repository
@Query(value = "SELECT c.appointments FROM Client c WHERE c.id = :cId")
List<Appointment> getAppointmentsById(Long cId);
2- If you don't want to make the relationship bidirectional, you should fetch the Client
object before searching it with the Appointment
repository methods.
// in your appointment repository
List<Appointment> findByClient(Client client);
// then you can fetch it anywhere
Client client = clientRepository.findById(cliendId);
List<Appointment> clientAppointments = appointmentRepository.findByClient(client);