I have a query with Criteria which consists of multiple joins of same entity. The amount of joins is dynamic, the code as following:
@Entity
public class Member {
@Id
Long id;
String name;
@OneToMany(...)
private List<MemberSpec> specs = new ArrayList<>();
}
@Entity
public class MemberSpec {
@Id
private Long id
private String specName;
}
// DTO
public class MemberDTO {
Member member;
MemberSpec[] memberSpecs;
public MemberDTO(Member member, MemberSpec... memberSpecs) {
this.member = member;
this.memberSpecs = memberSpecs;
}
}
// Repository
List<String> specs = List.of("Spec1", "Spec2"..."SpecN");
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MemberDTO> root = builder.createQuery(MemberDTO.class);
Root<Member> root = query.from(Member.class);
List<Selection<?>> joins = new ArrayList<>();
for (Spec specName : specs) {
Join<Member, MemberSpec> specsJoin = root.join("specs");
Predicate conditionName = builder.equal(specsJoin.get("specName").specName);
joins.add(specsJoin);
}
root.multiselect(joins);
List<MemberDTO> result = entityManager.createQuery(root).getResultList();
But is when this code executed then I receiving an exception:
org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [MemberDTO].
Expected arguments are: Member, MemberSpec, MemberSpec, MemberSpec [
select new MemberDTO(( generatedAlias3, generatedAlias0, generatedAlias1, generatedAlias2)
from Member as generatedAlias3
inner join generatedAlias3.specs as generatedAlias0
inner join generatedAlias3.specs as generatedAlias1
inner join generatedAlias3.specs as generatedAlias2
where ( ( generatedAlias0.specName=:param0 ) and
( generatedAlias1.specName=:param1 ) and
( generatedAlias2.specName=:param2 ) )
)
]
The exception reason is pretty clear - it's about Hibernate looks for DTO's constructor with exact number of arguments as the joins given. I thought since I used "..." operator I could have dynamic array of joins but obviously no. The problem is that number of joins is dynamic and I can't make different constructors with specific number of joined entity.
How can I achive it?