Java Hibernate无法使复合密钥正常工作

Java Hibernate无法使复合密钥正常工作,java,hibernate,Java,Hibernate,我有一个叫做WebAsset的类: public class WebAsset { private Long id; private String url; private int status; //more fields that are not relevent } 我需要能够显示WebAsset之间的关系,因此我为关系和复合键类创建了一个表 public class WebAssetReferencePK { private Long sourc

我有一个叫做WebAsset的类:

public class WebAsset {
    private Long id;
    private String url;
    private int status;
    //more fields that are not relevent
}
我需要能够显示WebAsset之间的关系,因此我为关系和复合键类创建了一个表

public class WebAssetReferencePK {
    private Long sourceAssetId;
    private Long targetAssetId;
}

public class WebAssetReference {
    private WebAssetReferencePK wpk;
    private Long updateTime;
}
我们被迫使用较旧版本的Hibernate,因此我们需要使用xml文件而不是注释。以下是引用类的映射:

<class name="ca.gc.cra.www.crawler.valueobject.WebAssetReference" table="webassetreference">
    <composite-id name="webAssetReferencePK" class="ca.gc.cra.www.crawler.valueobject.WebAssetReferencePK">
        <key-property name="sourceAsset" type="java.lang.Long" column="sourceAssetId" />
        <key-property name="targetAsset" type="java.lang.Long" column="targetAssetId" />
    </composite-id>
    <property name="updateTime" type="java.lang.Long" column="updatetime" not-null="true" />
</class>
以下是不起作用的HQL:

FROM WebAsset JOIN WebAssetReference WebAssetReference.WebAssetReferencePK.targetAsset=WebAsset WHERE WebAssetReference.WebAssetReferencePK.sourceAsset = :sourceAsset
我在HQL中遇到以下错误:错误-第1行:89:意外标记:


我会继续尝试,但我似乎无法理解HQL。

我发现了如何做到这一点。在我上面提到的例子中,它将不起作用,因为我有两列连接到同一个表。但是,如果我使用上面相同的WebAsset类,而使用该类:

 public class TreeNode implements Comparable<TreeNode>{

    private String nodeUrl;
    private Long id;
    private Boolean folder;
    private transient WebAsset nodeAsset = null; 
}
然后Hibernate可以正确地执行连接。结果将是一个列表,其中包含每个条目的对象数组。该对象包含属于联接的两个类。必须使用(Object[])强制转换对象才能访问元素,然后将每个元素强制转换到相应的类


我建议不要使用这种方法,因为Hibernate也会尝试加载所有连接的类。在上面的例子中,我从TreeNode中得到了1行,但它生成了19条select语句。我甚至尝试将连接的类设置为延迟加载,但它仍然生成所有选择。

我找到了一个接近的答案,但它并没有提供我所需要的。目前,我有一个解决方案,但它将被证明是缓慢的,因为它涉及多个数据库访问。一旦我找到了解决方案,如果有人没有首先找到答案,我会发布答案。
 public class TreeNode implements Comparable<TreeNode>{

    private String nodeUrl;
    private Long id;
    private Boolean folder;
    private transient WebAsset nodeAsset = null; 
}
<class name="ca.gc.cra.www.crawler.valueobject.TreeNode" table="TreeNode">
    <id name="id" type="java.lang.Long" column="treenode_id" >
        <generator class="identity"/> 
    </id>
    <many-to-one name="nodeAsset" class="ca.gc.cra.www.crawler.valueobject.WebAsset" column="nodeAsset_id" lazy="false" not-null="false" cascade="none" unique="true" />
    <property name="folder" type="java.lang.Boolean" column="folder" not-null="true" />
    <property name="nodeUrl" length="512"  type="java.lang.String" column="nodeUrl" not-null="true" />

    <set name="children" table="TreeNode" inverse="false" lazy="true" >
        <key column="parentnode_id"/>
            <one-to-many class="ca.gc.cra.www.crawler.valueobject.TreeNode" />
    </set>
</class>
Session session = HibernateUtil.getSession();
try {
    String hql = "FROM TreeNode tn JOIN tn.nodeAsset WHERE tn.id=5";
    Query query = session.createQuery(hql);
    List result = query.list();
    System.out.println("done");
} catch (HibernateException e) {
    e.printStackTrace();
    throw new Exception("Query failed", e);
} finally {
    session.flush();
    session.close();
}