QueryException:非法尝试取消引用集合Hibernate选择w /子类

时间:2017-06-22 22:51:52

标签: java hibernate spring-mvc hql

我是hibernate的新手,很难理解HQL。下面是我的DAO,它返回查询异常。我真的很感激任何帮助,我已经通过这个网站和官方文档仍然无法使其工作。谢谢!!

仅供参考:映射是.xml,无法切换到JPA

堆栈追踪:

type Exception report

message Request processing failed; nested exception is org.hibernate.QueryException: illegal attempt to dereference collection [feature0_.id.actors] with element property reference [name] [SELECT f from ar.edu.uces.progweb2.springmvc.model.Feature as f where f.name like :term or f.actors.name like :term or f.genre.name like :term order by f.name ASC ]

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.QueryException: illegal attempt to dereference collection [feature0_.id.actors] with element property reference [name] [SELECT f from ar.edu.uces.progweb2.springmvc.model.Feature as f where f.name like :term or f.actors.name like :term or f.genre.name like :term order by f.name ASC ]
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

org.hibernate.QueryException: illegal attempt to dereference collection [feature0_.id.actors] with element property reference [name] [SELECT f from ar.edu.uces.progweb2.springmvc.model.Feature as f where f.name like :term or f.actors.name like :term or f.genre.name like :term order by f.name ASC ]
    org.hibernate.hql.internal.ast.tree.DotNode$1.buildIllegalCollectionDereferenceException(DotNode.java:68)
    org.hibernate.hql.internal.ast.tree.DotNode.checkLhsIsNotCollection(DotNode.java:550)
    org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:246)
    org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:118)
    org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:114)
    org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:881)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1264)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4297)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:3913)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1947)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1900)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1897)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:794)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:595)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
    org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
    org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248)
    org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183)
    org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
    org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:105)
    org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
    org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168)
    org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:219)
    org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:197)
    org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1736)
    ar.edu.uces.progweb2.springmvc.dao.FeatureDAO.search(FeatureDAO.java:98)
    ar.edu.uces.progweb2.springmvc.dao.FeatureDAO$$FastClassByCGLIB$$3247faf2.invoke(<generated>)
    net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
    ar.edu.uces.progweb2.springmvc.dao.FeatureDAO$$EnhancerByCGLIB$$f55db758.search(<generated>)
    ar.edu.uces.progweb2.springmvc.controller.AppController.buscar(AppController.java:229)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
note The full stack trace of the root cause is available in the Apache Tomcat/8.0.37 logs.

HBM特征:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Qualified Class Names -->
<hibernate-mapping default-lazy="false">
<class name="ar.edu.uces.progweb2.springmvc.model.Feature" table="feature">
    <id name="id" type="int" column="id">
        <generator class="native"/>
    </id>
    <discriminator column="feature_type" type="string"/>
    <property name="name" column="name"/>
    <property name="runtime" column="runtime"/>
    <property name="coverImage" column="cover_image"/>
    <property name="storyline" column="storyline"/> 
    <set name="showtimes" inverse="true" cascade="all" fetch="join">
        <key column="feature_id"/>
        <one-to-many class="ar.edu.uces.progweb2.springmvc.model.Showtime" entity-name="ar.edu.uces.progweb2.springmvc.model.Showtime"/>
    </set>        
    <subclass name="ar.edu.uces.progweb2.springmvc.model.Movie" discriminator-value="M">
        <set name="actors" inverse="true" cascade="all" fetch="join">
            <key column="feature_id"/>
            <one-to-many class="ar.edu.uces.progweb2.springmvc.model.Actor" entity-name="ar.edu.uces.progweb2.springmvc.model.Actor"/>
        </set>      
    </subclass>
        <subclass name="ar.edu.uces.progweb2.springmvc.model.Documentary"  discriminator-value="D">
        <many-to-one name="genre" 
        column="documentary_genre_id"
        not-null="true" fetch="join"/>  
    </subclass>
</class>
</hibernate-mapping>

模特课(专题,电影,纪录片)

特点:

public abstract class Feature {

    private int id;
    private String name;
    private int runtime;
    private byte[] coverImage;
    private String storyline;
    private String featureType;
    private Set<Showtime> showtimes;

    public abstract boolean isMovie();      
    public abstract boolean isDocumentary();

    public Feature(){
        this.showtimes = new HashSet<Showtime>();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getRuntime() {
        return runtime;
    }

    public void setRuntime(int runtime) {
        this.runtime = runtime;
    }

    public byte[] getCoverImage() {
        return coverImage;
    }

    public void setCoverImage(byte[] coverImage) {
        this.coverImage = coverImage;
    }

    public String getStoryline() {
        return storyline;
    }

    public void setStoryline(String storyline) {
        this.storyline = storyline;
    }

    public String getFeatureType() {
        return featureType;
    }

    public void setFeatureType(String featureType) {
        this.featureType = featureType;
    }

    public Set<Showtime> getShowtimes() {
        return showtimes;
    }
    public void setShowtimes(Set<Showtime> showtimes) {
        this.showtimes = showtimes;
    }
}

电影:

public class Movie extends Feature {

    private Set<Actor> actors;

    @Override
    public boolean isMovie() {
        return true;
    }

    public Movie (){
        actors = new HashSet<Actor>();
    }
}

纪录片:

public class Documentary extends Feature{

    private Genre genre;

    @Override
    public boolean isDocumentary(){
        return true;
    }

    @Override
    public boolean isMovie() {
        return false;
    }

    public Documentary(){
        this.genre = new Genre();
    }

    public Genre getGenre() {
        return genre;
    }

    public void setGenre(Genre genre) {
        this.genre = genre;
    }       

}

DAO:

public List<Feature> search(SearchForm sf){
        StringBuffer query = new StringBuffer("SELECT f ");
        Map<String, Object> params = new HashMap<>();
        Session session = sessionFactory.getCurrentSession();
        switch (sf.getFeatureType()){   //0: Both, 1: Commercial Film, 2: Documentary
        case 0:
            query.append("from Feature as f "); 
            if (sf.getTerm() != null && !sf.getTerm().isEmpty()){
                query.append("where f.name like :term or f.actors.name like :term or f.genre.name like :term ");
                params.put("term","%"+ sf.getTerm() + "%");
            }
            break;
        case 1:         
            if (sf.getTerm() != null && !sf.getTerm().isEmpty()){
                query.append("from Movie m left join m.actors a where (a.name like :term or m.name like :term) ");
                params.put("term","%"+ sf.getTerm() + "%");
            } else {
                query.append("from Movie m ");
            }
            break;
        case 2:         
            if (sf.getTerm() != null && !sf.getTerm().isEmpty()){
                query.append("from Documentary d left join d.genre g where  (g.name like :term or d.name like :term) ");
                params.put("term", "%"+ sf.getTerm()+"%");
            } else {
                query.append("from Documentary d left join d.genre g "); 
            }
            break;
        }


        switch (sf.getOrder()){
            case "nameDesc":
                query.append("order by f.name DESC ");
                break;

            default:
                query.append("order by f.name ASC ");
                break;
            }

        System.out.println("Query: " + query.toString());
        Query q = session.createQuery(query.toString());
        Iterator<String> iter = params.keySet().iterator();
        while(iter.hasNext()){
            String k = iter.next();
            Object o = params.get(k);
            q.setParameter(k, o);
        }
        q.setFirstResult(this.resultsPerPage * sf.getPage());
        q.setMaxResults(this.resultsPerPage);
        //System.out.println("Search OK!");
        return q.list();
    }

1 个答案:

答案 0 :(得分:0)

解决了,我的hql相当草率

         case 0:
            query.append("from Feature f "); 
            if (sf.getTerm() != null && !sf.getTerm().isEmpty()){
                query.append("left join fetch f.actors a left join f.genre g where f.name like :term or a.name like :term or g.name like :term ");
                params.put("term","%"+ sf.getTerm() + "%");
            }
            break;

为您的实体考虑好的别名很重要,并且还了解到这些错误可能与缺少连接有关。谢谢!