Java 与createCriteria和createAlias的Hibernate关联

Java 与createCriteria和createAlias的Hibernate关联,java,hibernate,associations,criteria,alias,Java,Hibernate,Associations,Criteria,Alias,我有两个简单的映射: <class name="org.testing.Person" table="PERSON"> <id name="personId" type="long" column="PERSON_ID"> <generator class="native"/> </id> <property name="personName" type="string"

我有两个简单的映射:

<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>
它是有效的。 而不是像这样:

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:无法解析属性:street of:org.testing.Person
。我想这两个结果应该是一样的。我错在哪里? 提前谢谢

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

.setProjection(Projections.property(“street”)
始终按根标准操作。要投影加入的项目,必须使用发布的第一个版本。

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 );
}
createCriteria返回子条件,因此所有操作都基于子条件; 但是createAlias返回创建子标准的标准

示例1。 Ad-manytone-Ad组;它们都有“名称”属性

     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();
让我们假设adgroup中的名称为“aaaa” 广告中的名字是“bbbb” 在第一条语句中,结果的“name”值来自adGroup entity=“aaaa”。 在第二条语句中,结果的“name”值来自Ad实体“bbbb”

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

ps2:criteria2的第一个语句调用list(),但hibernate将从根criteria1开始处理;因此,最终的sql将包含criteria1中的“where ad.id=343909”

示例2。

教师和学生 一个学生一个学生

  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:无法解析属性:books of:Teacher; 因为书籍是学生的财产 这是createCriteria和createAlias之间的区别休眠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返回子条件,因此所有操作都基于子条件; 但是createAlias返回创建子标准的标准

示例1。 Ad-manytone-Ad组;它们都有“名称”属性

     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();
让我们假设adgroup中的名称为“aaaa” 广告中的名字是“bbbb” 在第一条语句中,结果的“name”值来自adGroup entity=“aaaa”。 在第二条语句中,结果的“name”值来自Ad实体“bbbb”

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

ps2:criteria2的第一个语句调用list(),但hibernate将从根criteria1开始处理;因此,最终的sql将包含criteria1中的“where ad.id=343909”

示例2。

教师和学生 一个学生一个学生

  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:无法解析属性:books of:Teacher; 因为书籍是学生的财产
这是createCriteria和createAlias之间的区别

为什么在第二个查询中使用createCriteria(“PersonalAddress”)?我之所以使用它,是因为Person类中有一个名为PersonalAddress的属性,它是与Address类关联的一端。为什么使用createCriteria(“PersonalAddress”)在第二个查询中,我使用它是因为Person类中有一个名为PersonalAddress的属性,它是Address类关联的一端