Hi guys,
Hibernate 5.6 with Spring 5.3 here. I’m just in the process of migrating Criteria API to JPA CriteriaBuilder. We use .hbm.xml mappings for the entities, no peristance.xml or something JPA specific
I’m doing something like this:
public List<ENTITY> findByCriteria(final Map<String, Object> criteriaMap, final List<String> fields, final Class<ENTITY> entityClass) {
CriteriaBuilder cb = this.getSession().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(MlsEventConsumerVOImpl.class);
Root root = cq.from(MlsEventConsumerVOImpl.class);
List<Predicate> predicates = new ArrayList<>();
// Construct predicates and projections...
cq.where(cb.and(predicates.toArray(new Predicate[0])));
Query query = getSession().createQuery(cq);
List<ENTITY> results = query.getResultList();
return results;
}
public class MlsEventConsumerVOImpl {
private Long rowguid;
private String path;
// More attributes
public MlsEventConsumerVOImpl () {
}
public void setRowguid(Long rowguid) { this.rowguid = roguid; }
// Further setters for every attribute
}
In the line
Query query = getSession().createQuery(cq);
I run into an exception:
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [com.myapp.mls.business.object.MlsEventConsumerVOImpl]. Expected arguments are: long, java.lang.String, java.lang.String, java.lang.String, boolean, java.util.Date, java.lang.String, java.util.Date, java.lang.String, java.lang.String, java.lang.String, java.util.Date, int, java.lang.String, java.lang.String, boolean [select new com.myapp.mls.business.object.MlsEventConsumerVOImpl(generatedAlias0.rowguid, generatedAlias0.path, generatedAlias0.denotation, generatedAlias0.status, generatedAlias0.scheduled, generatedAlias0.creationDate, generatedAlias0.creationUser, generatedAlias0.lastAction, generatedAlias0.sourceFilter, generatedAlias0.payloadFilter, generatedAlias0.interval, generatedAlias0.time, generatedAlias0.dayOfMonth, generatedAlias0.weekdays, generatedAlias0.notificationTemplatePath, generatedAlias0.runWithoutEvent) from com.myapp.mls.business.object.MlsEventConsumerVOImpl as generatedAlias0 where ( generatedAlias0.scheduled=:param0 ) and ( generatedAlias0.status=:param1 )]
at deployment.myapp-clienta.war//org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
at deployment.myapp-clienta.war//org.hibernate.hql.internal.ast.ErrorTracker.throwQueryException(ErrorTracker.java:93)
at deployment.myapp-clienta.war//org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:282)
at deployment.myapp-clienta.war//org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192)
at deployment.myapp-clienta.war//org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
at deployment.myapp-clienta.war//org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
at deployment.myapp-clienta.war//org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73)
at deployment.myapp-clienta.war//org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162)
at deployment.myapp-clienta.war//org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:636)
at deployment.myapp-clienta.war//org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:748)
I have made sure that for every attribute in my projection, a corresponding attribute + public setter is available in MlsEventConsumerVOImpl. What else could i check?
Edit: I have had a look into the class that is reponsible for selecting the appropriate constructur: org/hibernate/internal/util/ReflectHelper.java
The method getConstructor(…) works in a way where it accepts only constructors that have the same arguments that the select query itself provides as return values (which is never 0, so what’s the sense of the no-args constructor?). I don’t think this is correct, otherwise I would have to provide an endless number of constructors to my entity when the composition of the returned fields is variable.