Java HQL 左联接:预期加入的路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1262298/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 07:32:23  来源:igfitidea点击:

HQL left join: Path expected for join

javahibernatehql

提问by

I am new at Hibernate, and I have a question regarding HQL Left join.

我是 Hibernate 的新手,我有一个关于 HQL Left join 的问题。

I try to left join 2 tables, patient and provider, and keep getting "Path expected for join!" error on the second table. Appreciate it if anybody can help on this issue!

我尝试离开加入 2 个表,患者和提供者,并不断收到“预期加入的路径!” 第二张桌子上的错误。如果有人可以帮助解决这个问题,不胜感激!

Here is the mapping of the 2 tables/classes:

这是 2 个表/类的映射:

patient.hbm.xmL:

患者.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ccg.db.test">
    <class name="patient" table="patient">
        <id name="patientId" column="patientId" type="int">
            <generator class="native"/>
        </id>
        <property name="patientName" type="string" >
           <column name="patientName" /> 
        </property>
        <property name="providerId" type="string" >
            <column name="provId" /> 
        </property>
        <many-to-one name="provider" column="providerId" class="provider" /> 
    </class>
</hibernate-mapping>


provider.hbm.xml:

提供者.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ccg.db.test">
    <class name="provider" table="provider">
        <id name="providerId" column="providerId">
            <generator class="native" />
        </id>
        <property name="providerName" column="providerName" />
    </class>
</hibernate-mapping>


pojo:

pojo:

patient.java

package com.ccg.db.test;

import java.io.Serializable;
import java.util.List;
import org.hibernate.Session;

public class patient 
implements Serializable
{
    private int patientId;
    private String patientName;
    private String providerId; // foreign key to provider

    private static final long serialVersionUID = 81073;

    public static void load(Session session, List<String> values){
        patient PatientInfo = new patient(); 

        PatientInfo.setPatientId(Integer.parseInt(values.get(0)));
        PatientInfo.setPatientName( values.get(1));
        PatientInfo.setProviderId( values.get(2) );

        session.save( PatientInfo );
    }

    /**
    * @return the PatientId
    */
    public int getPatientId() {
        return patientId;
    }

    /**
    * @param PatientId the PatientId to set
    */
    public void setPatientId(int PatientId) {
        this.patientId = PatientId;
    }

    /**
    * @return the PatientName
    */
    public String getPatientName() {
        return this.patientName;
    }

    /**
    * @param PatientName the PatientName to set
    */
    public void setPatientName(String PatientName) {
        this.patientName = PatientName;
    }

    /**
    * @return the ProvId
    */
    public String getProviderId() {
        return this.providerId;
    }

    /**
    * @param id the ProviderId to set
    */
    public void setProviderId( String id ) {
        this.providerId = id;
    }

    /**
    * @return the ProvId
    */
    public String getProvider() {
        return this.providerId;
    }

    /**
    * @param id the ProviderId to set
    */
    public void setProvider( String id ) {
        this.providerId = id;
    }  

    /**
    * @param args
    */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
    }
}

provider.java:

package com.ccg.db.test;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;

public class provider 
implements Serializable
{
    private String providerId;
    private String providerName;

    //private int patientId;
    //private int providerSpec; 

    private static final long serialVersionUID = 81073;

    public static void load(Session session, List<String> values){
        provider ProviderInfo = new provider(); 

        ProviderInfo.setProviderId( values.get(0) );
        ProviderInfo.setProviderName( values.get(1));
        //ProviderInfo.setProviderSpec( Integer.parseInt(values.get(2)) );

        session.save( ProviderInfo );
    }

    /**
    * @return the ProviderName
    */
    public String getProviderName() {
        return providerName;
    }

    /**
    * @param ProviderName the ProviderName to set
    */
    public void setProviderName(String name) {
        this.providerName = name;
    }

    /**
    * @return the ProvId
    */
    public String getProviderId() {
        return this.providerId;
    }

    /**
    * @param id the ProvId to set
    */
    public void setProviderId( String id ) {
        this.providerId = id;
    }

    /*
    public int getPatientId() {
        return this.patientId;
    }

    public void setPatientId( int id ) {
        this.patientId = id;
    }
    */

    /**
    * @param args
    */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
    }
}


Here is the left join query:

这是左连接查询:

select
    pat.patientId, pat.patientName
from
    patient as pat 
left join
    provider as pro 
where
    pat.providerId = pro.providerId


and here is the result:

结果如下:

0:50:08,479 INFO query:156 - Query = outerJoin
10:50:08,479 INFO query:157 - select
pat.patientId, pat.patientName
from
patient as pat 
left join
provider as pro 
where
pat.providerId = pro.providerId

10:50:08,698 ERROR PARSER:33 - Path expected for join!
10:50:08,698 ERROR PARSER:33 - Invalid path: 'pro.providerId'
10:50:08,698 ERROR PARSER:33 - right-hand operand of a binary operator was null
10:50:08,698 ERROR query:184 - Problem generating query.
org.hibernate.hql.ast.QuerySyntaxException: Path expected for join! [select
pat.patientId, pat.patientName
from
com.ccg.db.test.patient as pat 
left join
provider as pro 
where
pat.providerId = pro.providerId
]
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:31)
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:24)
at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:59)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:235)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:160)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
at com.ccg.db.query.QueryManager.query(QueryManager.java:163)
at com.ccg.db.query.QueryManager.query(QueryManager.java:139)
at com.ccg.db.query.QueryManager.main(QueryManager.java:80)

回答by digitaljoel

Your patient has a reference to the provider, and also has the provider id as a property. I would probably get rid of the provider id property on the patient and just have the reference to the provider. Then your query should be something like this.

您的患者有对提供者的引用,并且还具有提供者 ID 作为属性。我可能会去掉患者身上的 provider id 属性,而只引用提供者。那么你的查询应该是这样的。

select pat.patientId, pat.patientName 
from patient as pat 
left join pat.provider as pro

To join, you need the association path from your patient to your provider, which in this case is pat.provider. Then hibernate will automatically use the "column" specified in the many-to-one mapping to join into the provider table. In your case, the join doesn't make a lot of sense since you aren't querying on any properties of the provider, so something like this might make more sense

要加入,您需要从患者到提供者的关联路径,在本例中为 pat.provider。然后hibernate会自动使用多对一映射中指定的“列”加入到提供者表中。在您的情况下,连接没有多大意义,因为您没有查询提供者的任何属性,所以这样的事情可能更有意义

select pat 
from patient as pat 
join pat.provider as pro 
where pat.patientName = 'John' 
and pro.name = 'United Healthcare'

There you are able to filter your patient list to patients named John that have United Healthcare as the provider.

在那里,您可以将您的患者列表过滤为以 United Healthcare 作为提供者的名为 John 的患者。