【问题标题】:Hibernate association with createCriteria and createAliasHibernate 与 createCriteria 和 createAlias 的关联
【发布时间】:2012-01-03 23:02:13
【问题描述】:

我有两个简单的映射:

<class name="org.testing.Person" table="PERSON">
        <id name="personId" type="long" column="PERSON_ID">
            <generator class="native"/>
        </id>
        <property name="personName" type="string" not-null="true" column="PERSON_NAME"/>
        <many-to-one name="personAddress" class="org.testing.Address" column="PERSON_ADDRESS"    not-null="true" cascade="all" unique="true"/>
</class>

<class name="org.testing.Address" table="ADDRESS">
    <id name="addressId" type="long" column="ADDRESS_ID">
        <generator class="native" />
    </id>
    <property name="street" column="ADDRESS_STREET" type="string" />
    <property name="city" column="ADDRESS_CITY" type="string" />
    <property name="state" column="ADDRESS_STATE" type="string" />
</class>

我尝试像这样获取人员地址的属性:

session.createCriteria(Person.class)
                    .add(Restrictions.eq("personName", "Frodo"))
                    .createAlias("personAddress", "pa")
                    .setProjection(Projections.property("pa.street"))
                    .list();

它有效。 比这样:

session.createCriteria(Person.class)
                    .add(Restrictions.eq("personName", "Frodo"))
                    .createCriteria("personAddress")
                    .setProjection(Projections.property("street"))
                    .list();

它抛出:org.hibernate.QueryException: could not resolve property: street of: org.testing.Person。我认为两者都应该给出相同的结果。我哪里错了? 提前致谢!

【问题讨论】:

  • 为什么在第二个查询中使用 createCriteria("personAddress")
  • 我正在使用它,因为在 Person 类中有一个名为 personAddress 的属性,它是与 Address 关联的一端

标签: java hibernate associations criteria alias


【解决方案1】:

.setProjection(Projections.property("street")) 始终在根标准上运行。要投影加入的项目,您必须使用您发布的第一个版本。

【讨论】:

    【解决方案2】:

    休眠 3.3.2;

    让我们看看代码源:

     public Criteria createAlias(String associationPath, String alias, int joinType) {
        new Subcriteria( this, associationPath, alias, joinType );
        return this;
    }
    
    
    public Criteria createCriteria(String associationPath, int joinType) {
        return new Subcriteria( this, associationPath, joinType );
    }
    

    createCriteria return sub Criteria ,所以所有的操作都在 sub Criteria 上; 但 createAlias 是返回创建子标准的标准;

    示例 1. 广告 manyToone 广告组;它们都有“名称”属性

         Criteria criteria1    = s.createCriteria(Ad.class, "ad").add(Restrictions.eq("ad.id", Long.valueOf(343909))) ;
         Criteria criteria2    =  criteria1.createCriteria("adGroup")
                        .setProjection(Projections.property("name"))
             List list  = criteria2.list();
    
    
        List list = s.createCriteria(Ad.class, "ad").add(Restrictions.eq("ad.id", Long.valueOf(343909)))
                        .createAlias("adGroup", "adGroup")
                        .setProjection(Projections.property("name"))
                        .list();
    

    假设广告组中的名称是“aaaa” 广告中的名字是“bbbb” 在第一个语句中,结果的“名称”值来自 adGroup 实体 =“aaaa”。 在第二个语句中,结果的“名称”值来自广告实体“bbbb”。

    ps1:如果广告组实体中没有“名称”属性,但在广告实体中,第一条语句将抛出 Exception: org.hibernate.QueryException: could not resolve property: name of: AdGroup ; 但是如果你改为“ .setProjection(Projections.property("ad.name")) ”,返回广告名称的值就可以了

    ps2 :first statement call list() by criteria2 ,但hibernate会从根条件=criteria1开始处理;所以最终的 sql 将包含来自 criteria1 的“ where ad.id =343909 ”;

    示例 2。

    老师 oneToMany 学生 学生一对多学生

      List list1 = s.createCriteria(Teacher.class, "teacher").add(Restrictions.eq("teacher.id", Long.valueOf(343909)))
                        .createCriteria("students").createCriteria("books")
                        .list();
    
    
    
     List list2 = s.createCriteria(Teacher.class, "teacher").add(Restrictions.eq("teacher.id", Long.valueOf(343909)))
                        .createAlias("students").createCriteria("books").setProjection(Projections.property("name"))
                        .list();
    

    第二条语句会抛出异常:org.hibernate.QueryException: could not resolve property: books of: Teacher; 因为书籍是学生的财产 这就是 createCriteria 和 createAlias 的区别;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-21
      • 2014-10-16
      • 1970-01-01
      相关资源
      最近更新 更多