Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate:动态连接多个表_Java_Hibernate_Join_Criteria_Hibernate Criteria - Fatal编程技术网

Java Hibernate:动态连接多个表

Java Hibernate:动态连接多个表,java,hibernate,join,criteria,hibernate-criteria,Java,Hibernate,Join,Criteria,Hibernate Criteria,我是新加入Hibernate的,我正在尝试动态加入更多的表。我用三个表构建了一个示例:Employee、Address、Country。我想找回某个国家的所有员工。这里是我的配置文件: <class entity-name="Employee"> <id name="id" type="int" column="id"> <generator class="native"/> </id>

我是新加入Hibernate的,我正在尝试动态加入更多的表。我用三个表构建了一个示例:Employee、Address、Country。我想找回某个国家的所有员工。这里是我的配置文件:

 <class entity-name="Employee">
        <id name="id" type="int" column="id">
            <generator class="native"/>
        </id>
        <property name="firstName" column="first_name" type="string"/>
        <property name="lastName" column="last_name" type="string"/>
        <property name="salary" column="salary" type="int"/>

        <many-to-one name="address" column="address" unique="true"
                     class="Address" not-null="true"/>
    </class>

    <class entity-name="Address">
        <id name="id" type="int" column="id">
            <generator class="native"/>
        </id>
        <property name="street" column="street_name" type="string"/>
        <property name="city" column="city_name" type="string"/>
        <property name="state" column="state_name" type="string"/>
        <property name="zipcode" column="zipcode" type="string"/>

        <many-to-one name="country" column="country" unique="true"
                     class="Country" not-null="true"/>
    </class>

    <class entity-name="Country">
        <id name="id" type="int" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name" type="string"/>
        <property name="code" column="code" type="string"/>
    </class>
我得到了正确的结果,但我的目标不是手动指定起始表和筛选表之间的整个路径:我希望hibernate为我完成这项工作。我想这样写:

  List employees = session.createCriteria("Employee")
          .createCriteria("country")
          .add(Restrictions.eq("code","IT"))
          .list();
但是我得到了错误信息

org.hibernate.QueryException: could not resolve property: country of: Employee

Hibernate只是一个用于隐藏SQL表达式的包装器或抽象层

在您的工作示例中,Hibernate构建了一个SQL select语句,创建双连接并返回所需的输出。您正在向Hibernate提供如何过滤关联表的“知识”。与编写自己的SQL语句相同

但在第二个示例中,您希望Hibernate从第一个表中猜测第二级关联。Hibernate只需查找表Employee是否有列/外键国家/地区,但找不到该列/外键国家/地区。因此错误是:无法解析属性:国家/地区:雇员

您不能指望Hibernate会产生这种神奇的效果,因为它会产生各种各样的错误查询

只是为了举例说明

如果您的员工有两个地址类型的字段:

<class entity-name="Employee">
        <id name="id" type="int" column="id">
            <generator class="native"/>
        </id>
        <property name="firstName" column="first_name" type="string"/>
        <property name="lastName" column="last_name" type="string"/>
        <property name="salary" column="salary" type="int"/>

        <many-to-one name="bussiness_address" column="bussiness_address" unique="true"
                     class="Address" not-null="true"/>
        <many-to-one name="home_address" column="home_address" unique="true"
                     class="Address" not-null="true"/>
    </class>
按家庭或业务地址或两者筛选国家/地区? 或者想象一下这样一种情况,即通过每个表中的id字段进行过滤


总而言之:Hibernate不能变魔术,它只是用来隐藏原始SQL。

如果我将您的查询翻译成Java语言,您要做的就是直接从employee获得coutry的价值。但在Java中,可能会出现编译错误。这样的东西在Java、Hibernate或普通SQL中都不会自动工作。员工和国家/地区之间没有直接链接,但有一系列链接:员工->地址->国家/地区

为了用Java方式解决这个问题,可以直接从employee获得对country的二次引用。然后调用employee.getAddress().getCountry()和employee.getCountry()将相等

要在hibernate中实现这一点,您需要向Employee添加新的field country,并使用entity Address将其映射为与entity country的不可修改的多对多关系。这只会将2个hibernate连接减少为一个,不能重复应用于2个以上的连接


如果此解决方案适合您,我可以为您提供示例语法。

好的,我理解您的比较。关键是Hibernate有一个查询(生成器)引擎,但它不能像我想象的那样动态地找到图中两个实体之间的路径。Hibernate需要在查询中加入一个联接,以提供通过address实体从雇员到国家/地区的路径
<class entity-name="Employee">
        <id name="id" type="int" column="id">
            <generator class="native"/>
        </id>
        <property name="firstName" column="first_name" type="string"/>
        <property name="lastName" column="last_name" type="string"/>
        <property name="salary" column="salary" type="int"/>

        <many-to-one name="bussiness_address" column="bussiness_address" unique="true"
                     class="Address" not-null="true"/>
        <many-to-one name="home_address" column="home_address" unique="true"
                     class="Address" not-null="true"/>
    </class>
List employees = session.createCriteria("Employee")
          .createCriteria("country")
          .add(Restrictions.eq("code","IT"))
          .list();