We have 3 records as ProjectionConstructor to map the projections from ES backend
Doctor.java
public record Doctor(
UUID id,
String fullName,
@ObjectProjection(includeDepth = 2) DoctorDetails doctorDetails,
@ObjectProjection(includeDepth = 1) List<DoctorEspecialty> doctorEspecialties // **a Many To Many linking for `Especialties`
){}
DoctorEspecialty.java
@ProjectionConstructor
public record DoctorEspecialty(
UUID id,
@ObjectProjection(includeDepth = 1) Especialty especialtyCode,
@ObjectProjection(includeDepth = 1) Doctor doctor) {}
Especialty.java
@ProjectionConstructor
public record Especialty(
UUID id,
String especialtyName,
String localName
Integer code,
@ObjectProjection(includeDepth = 1) Language language) {}
We are using the below code to retrieve the Doctor data and use mapstruct to map the data, ex: doctorMapper:
List<**.projection.Doctor> doctors = searchSession
.search(Doctor.class)
.select(**.projection.Doctor.class)
.where((f, root) -> {
root.add(f.matchAll());
root.add(
// dynamic criteria based on request
})
.fetchHits(pageable.getPageNumber() * pageable.getPageSize(), pageable.getPageSize());
return new PageImpl<DoctorDTO>(doctors.stream().map(doctorMapper::toDto).collect(Collectors.toList()), pageable, suppliers.size());
Getting below error:
- "status" : 500,
- "detail" : "HSEARCH400655: Invalid cardinality for projection on field 'doctorEspecialties.especialtyCode.id': the projection is single-valued, but this field is effectively multi-valued in this context, because parent object field 'doctorEspecialties' is multi-valued. Either call '.multi()' when you create the projection on field 'doctorEspecialties.especialtyCode.id', or wrap that projection in an object projection like this: 'f.object("doctorEspecialties").from().as(...).multi()'.",
It works fine if we use a composite record, but that leads to duplicate/redundent code in both projection-dtos and mapstruct mappers.
Thanks in advance for any help