Hi,
I am stuck trying to build this criteria API query and need some help to understand the exception thrown by Hibernate. Would appreciate any clarification on what is happening and the changes needed to run this query.
the issue is with
Code:
er.fetch("shipper"); er.fetch("carrier"); and er.fetch("consignee");
I could work around by replacing fetch by join but that leads me to a N+1 problem which I want to avoid. The reason I am using DTO is because this is a response for a HTTP GET query and I need it to be as fast as possible as this query scans the whole database.
Thank you very much
# EXCEPTION
##############
Quote:
SEVERE: Servlet.service() for servlet [jersey-servlet] in context with path [/returnitRest] threw exception [java.lang.IllegalArgumentException: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=generatedAlias1,role=returnitRest.Ereturn.shipper,tableName=user,tableAlias=user1_,origin=ereturn ereturn0_,columns={ereturn0_.shipper ,className=returnitRest.User}}] [select new returnitRest.Ereturn(generatedAlias0.rma, generatedAlias0.shipper, generatedAlias0.consignee, generatedAlias0.carrier, generatedAlias0.status, generatedAlias0.returnMethod) from returnitRest.Ereturn as generatedAlias0 inner join fetch generatedAlias0.shipper as generatedAlias1 inner join fetch generatedAlias0.carrier as generatedAlias2 inner join fetch generatedAlias0.consignee as generatedAlias3 where 1=1]] with root cause
org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=generatedAlias1,role=returnitRest.Ereturn.shipper,tableName=user,tableAlias=user1_,origin=ereturn ereturn0_,columns={ereturn0_.shipper ,className=returnitRest.User}}]
at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:216)
at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:1011)
at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:779)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:675)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:311)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:259)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:261)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:545)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:654)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3307)
at org.hibernate.query.criteria.internal.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:318)
at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:127)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3600)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:203)
at returnitRest.Ereturn.fetch(Ereturn.java:621)
at returnitRest.EreturnResource.filterEreturn(EreturnResource.java:463)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:76)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:148)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:191)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
# CRITERIA AI QUERY
##########################
Code:
public static List<Ereturn> fetch(FilterEreturn filter, Boolean disabled) {
EntityManager em = Utils.initEntityManager();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Ereturn> criteria = builder.createQuery( Ereturn.class );
Root<Ereturn> er = criteria.from(Ereturn.class);
er.fetch("shipper"); <<================================================= THROWS EXCEPTION (code works fine when fetch is replaced by join)
er.fetch("carrier"); <<================================================= THROWS EXCEPTION (code works fine when fetch is replaced by join)
er.fetch("consignee"); <<================================================= THROWS EXCEPTION (code works fine when fetch is replaced by join)
criteria.select(builder.construct(
Ereturn.class,
er.get("rma"),
er.get("shipper"),
er.get("consignee"),
er.get("carrier"),
er.get("status"),
er.get("returnMethod")
));
List<Predicate> predicates = new ArrayList<>();
// if (filter.getShipperId() != null) {
// predicates.add(builder.equal(er.get( "shipper" ), filter.getShipperId()));
// }
//
// if (filter.getConsigneeId() != null) {
// predicates.add(builder.equal( er.get( "consignee" ), (filter.getConsigneeId())));
// }
//
// if (filter.getCarrierId() != null) {
// predicates.add(builder.equal( er.get( "carrier" ), (filter.getCarrierId())));
// }
if (filter.getReturnMethod() != null && !filter.getReturnMethod().equals("")) {
predicates.add(builder.equal( er.get( "returnMethod" ), (filter.getReturnMethod())));
}
if (filter.getRma() != null && !filter.getRma().equals("")) {
predicates.add(builder.equal( er.get( "rma" ), (filter.getRma()))); // RMA must match the input otherwise scan by RMA may return multiple values
}
if (filter.getStatus() != null && !filter.getStatus().equals("")) {
predicates.add(builder.equal( er.get( "status" ), (filter.getStatus())));
}
criteria.where(
builder.and(predicates.toArray(new Predicate[predicates.size()]))
);
List<Ereturn> ers = em.createQuery(criteria).getResultList();
// Fetching lazy values
ers.forEach( ereturn -> { ereturn.getProductItems().size(); ereturn.getParcels().size(); });
// em.close();
return ers;
}