Спящая ассоциация с createCriteria и createAlias - PullRequest
1 голос
/ 04 января 2012

У меня есть два простых сопоставления:

<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.Я предполагаю, что оба должны дать тот же результат.Где я не прав?Заранее спасибо!

Ответы [ 2 ]

9 голосов
/ 29 марта 2013

в спящем режиме 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 многоToone Adgroup; все они имеют свойства "name"

     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" в первом утверждении значение name называется результатом от adGroup entity = "aaaa". во втором утверждении значение name называется "result" из рекламного объекта "bbbb".

ps1: если в сущности группы объявлений отсутствуют свойства "name", но в сущности объявления первый оператор выдаст исключение: org.hibernate.QueryException: не удалось разрешить свойство: name of: AdGroup; но если вы измените на ".setProjection (Projection.property (" ad.name "))", будет нормально вернуть значение имени объявления

ps2: список вызовов первого оператора () по критериям2, но режим гибернации будет обрабатываться из корневых критериев = критерии1; итоговый sql будет содержать "where ad.id = 343909" из критерия 1;

пример 2.

enter image description here

учитель oneToMany ученик студент 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: не удалось разрешить свойство: books of: Teacher; потому что книги являются собственностью студента это разница между createCriteria и createAlias;

9 голосов
/ 12 января 2012

.setProjection(Projections.property("street")) всегда действует по корневым критериям.чтобы проецировать присоединенные элементы, вы должны использовать первую опубликованную вами версию.

...