Hibernate与createCriteria和createAlias的关联

cat*_*dog 1 java alias hibernate criteria associations

我有两个简单的地图:

<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>
Run Code Online (Sandbox Code Playgroud)

<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>
Run Code Online (Sandbox Code Playgroud)

我试着得到这样的人物地址:

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

它的工作原理.比这样:

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

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

Fir*_*iro 9

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


phi*_*hil 9

hibernate 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 );
}
Run Code Online (Sandbox Code Playgroud)

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

示例1. Ad manyToone adgroup; 他们都有"名字"属性

     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();
Run Code Online (Sandbox Code Playgroud)

让我们说广告组中的名称是"aaaa",广告中的名称在第一个语句中是"bbbb",结果的"名称"值来自adGroup entity ="aaaa".在第二个语句中,结果的"名称"值来自广告实体"bbbb".

ps1:如果adgroup实体中没有"name"属性,但在ad实体中,first语句将抛出异常:org.hibernate.QueryException:无法解析属性:name of:AdGroup; 但如果您更改为".setProjection(Projections.property("ad.name"))",则可以返回广告名称的值

ps2:第一个语句调用list()by criteria2,但hibernate将从root criteria = 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();
Run Code Online (Sandbox Code Playgroud)

第二个语句将抛出异常:org.hibernate.QueryException:无法解析属性:books of:Teacher; 因为书籍是学生的财产, 这是createCriteria和createAlias之间的区别;