Bill F
Bill F

Reputation: 731

length() in HQL statement not working

So I'm having some issues with the HQL statement. The statement node where node.dflag=? and length(node.path)=? and node.rootEntityId=? should be a valid HQL statement based on this reference - section 14.10. Expressions.

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);

However, when I try to run the code on my web server(using tomcat), I get this error:

 [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)

These are my gradle dependencies:

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'

When I remove the length() part, it works fine.

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

What am I missing that I can't use the length() in my HQL statements?

Please let me know if you need more info.

EDIT:

TRoot.java contains dflag and rootEntityId

@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;
    }

}

Upvotes: 2

Views: 3315

Answers (1)

cнŝdk
cнŝdk

Reputation: 32145

This has nothing to do with using length() with HQL.

It's an encapsulation problem here, because in your SystemComponentRef bean you declared path as protected so it won't be accessible from the HQL query in length(node.path), because in Hibernate, HQL is an object-oriented query language, similar to SQL, but instead of operating on tables and columns, HQL works with persistent objects and their properties.

And that's why you got the Exception:

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

Which is saying that the property path can't be resolved, in other words is not found(unreachable).

Solution:

You need to change the modifier to private and use accessors so it respects encapsulation rules and can be accessed ouside your class package, and you need to keep in mind that Protected fields in base class are bad.

Java Access modifiers:

I suggest you to take a look at Controlling Access to Members of a Class Java Tutorial for further details.

Upvotes: 3

Related Questions