HQL语句中的length()不起作用

时间:2017-05-19 23:04:21

标签: java spring hibernate hql hibernate-mapping

所以我在HQL语句中遇到了一些问题。语句node where node.dflag=? and length(node.path)=? and node.rootEntityId=?应该是基于this reference - section 14.10. Expressions的有效HQL语句。

StringBuilder hql = new StringBuilder(100);
hql.append("from ").append(SystemComponentRef.class.getName()).append(" node where node.dflag=? and length(node.path)=? and node.rootEntityId=?");
List<?> list = db.find(SystemComponentRef.class, hql.toString(), 0, 8,  SystemEntity.SYS_ROOT_ENTITY_ID);

但是,当我尝试在我的Web服务器上运行代码时(使用tomcat),我收到此错误:

 [localhost-startStop-1] ERROR backend.HibernateEntityDao - Executing hql statement from backend.SystemComponentRef node where node.dflag=? and length(node.path)=? and node.rootEntityId=? has incurred an error
org.springframework.orm.hibernate3.HibernateQueryException: could not resolve property: path of: backend.SystemComponentRef [from backend.SystemComponentRef node where node.dflag=? and length(node.path)=? and node.rootEntityId=?]; nested exception is org.hibernate.QueryException: could not resolve property: path of: backend.SystemComponentRef [from backend.SystemComponentRef node where node.dflag=? and length(node.path)=? and node.rootEntityId=?]
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:656)
    at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:412)
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
    at backend.HibernateEntityDao.find(HibernateEntityDao.java:107)
    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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
    at com.sun.proxy.$Proxy57.find(Unknown Source)
    at backend.EntitySupporterDealImpl.find(EntitySupporterDealImpl.java:82)
    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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
    at com.sun.proxy.$Proxy63.find(Unknown Source)
    at backend.SystemComponentDealImpl.getSecurityRootNode(SystemComponentDealImpl.java:214)
    at backend.SystemInitTaskImpl.createRootDef(SystemInitTaskImpl.java:209)
    at backend.SystemInitTaskImpl.runInitTask(SystemInitTaskImpl.java:47)
    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.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:344)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:295)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:130)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:396)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1507)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:938)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4727)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5189)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:596)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1805)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

这些是我的gradle依赖项:

compile group: 'org.springframework', name: 'spring-core', version: '3.2.16.RELEASE'
compile group: 'org.springframework', name: 'spring-web', version: '3.2.16.RELEASE'
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.10.Final'
compile group: 'org.hibernate', name: 'hibernate-validator', version: '5.4.1.Final'
compile group: 'org.hibernate.hql', name: 'hibernate-hql-parser', version: '1.1.0.Final'

当我删除length()部分时,它可以正常工作。

hql.append("from ").append(SystemComponentRef.class.getName()).append(" d where d.dflag=? and d.rootEntityId=?");
List<?> list = db.find(SystemComponentRef.class, hql.toString(), 0, SystemEntity.SYS_ROOT_ENTITY_ID);
//this code works fine

我错过了什么,我不能在我的HQL语句中使用length()

如果您需要更多信息,请与我们联系。

编辑:

TRoot.java包含dflagrootEntityId

@Entity
@Table(name = "sysreference")
public class SystemComponentRef extends TRoot{

    private String name;

    protected String path;

    protected String parentId;

    protected Integer treeRecycleFlag;

    protected Integer treeDeleteFlag;


    @Column(name = "name")
    public String getName() {
        return name;
    }

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

    @Column(name = "parent_id")
    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    @Column(name = "path")
    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @Column(name = "recycle_flag")
    public Integer getTreeRecycleFlag() {
        return treeRecycleFlag == null ? 0 : treeRecycleFlag;
    }


    public void setTreeRecycleFlag(Integer treeRecycleFlag) {
        this.treeRecycleFlag = treeRecycleFlag;
    }

    @Column(name = "delete_flag")
    public Integer getTreeDeleteFlag() {
        return treeDeleteFlag == null ? 0 : treeDeleteFlag;
    }

    public void setTreeDeleteFlag(Integer treeDeleteFlag) {
        this.treeDeleteFlag = treeDeleteFlag;
    }

}

1 个答案:

答案 0 :(得分:2)

这与将length()HQL一起使用无关。

这是一个封装问题,因为在您的SystemComponentRef bean中,您将path声明为protected,因此无法从length(node.path)中的HQL查询访问它,因为在Hibernate中,HQL 是一种面向对象的查询语言,类似于SQL,但不是在表和列上操作,而是使用持久性对象和他们的财产。

这就是你得到例外的原因:

could not resolve property: path of: backend.SystemComponentRef [from backend.SystemComponentRef node where node.dflag=? and length(node.path)=?

这说明属性path 无法解析,换句话说找不到(无法访问)。

<强>解决方案:

您需要将修饰符更改为private并使用accessors,以便它尊重封装规则,并且可以在您的类包之外访问,并且您需要记住Protected fields in base class are bad

Java Access modifiers

我建议您查看Controlling Access to Members of a Class Java Tutorial了解更多详情。