-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: criteria JAP api complaining about selection
PostPosted: Tue Jan 02, 2018 6:34 pm 
Newbie

Joined: Mon Jan 01, 2018 3:13 am
Posts: 3
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;
    }


Top
 Profile  
 
 Post subject: Re: criteria JAP api complaining about selection
PostPosted: Wed Jan 03, 2018 9:11 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Fetch means to initialize the association while returning the entity. But you are not returning the Root entiy, but a projection:

Code:
criteria.select(builder.construct(
                Ereturn.class,
                er.get("rma"),
                er.get("shipper"),
                er.get("consignee"),
                er.get("carrier"),
                er.get("status"),
                er.get("returnMethod")
        ));


Return the root entity and it will work.


Top
 Profile  
 
 Post subject: Re: criteria JAP api complaining about selection
PostPosted: Wed Jan 03, 2018 12:43 pm 
Newbie

Joined: Mon Jan 01, 2018 3:13 am
Posts: 3
thank you for your response,

please forgive me if I am wrong but I was under the impression that I can only return 1 root entity. I am already returning Ereturn as root so how can I return both root and ProductItem as root entities?

thank you very much


Top
 Profile  
 
 Post subject: Re: criteria JAP api complaining about selection
PostPosted: Wed Jan 03, 2018 1:35 pm 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Just do it like this:

Code:
criteria.select(er);


and it will work.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.