참조 : http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html

Member(1) --- (*)Messenger 의 관계에서 다음과 같이 데이타가 들어있습니다.

Member m1 --- Messenger msg1("seal", MSN)
Member m1 --- Messenger msg2("seal2", Skype)
Member m3 --- Messenger msg3("keesun", MSN)

이 때 "MSN 메신저가 있는 모든 멤버"를 가져 오려면 join을 해야 합니다. Criteria를 사용해서 Join을 하는 방법은 두 가지가 있습니다.

1. createCriteria() 메소드 사용하기.

    public void testCriteriaJoin1(){
        insertDatas();
        final KMessengerType messengerType = KMessengerType.MSN;

        Criteria c = s.createCriteria(KMember.class)
                      .createCriteria("messengers")
                        .add(Restrictions.eq("m_type", messengerType));

        assertEquals(2, c.list().size());
    }

2. createAlias() 메소드 사용하기.

    public void testCriteriaJoin2(){
        insertDatas();
        final KMessengerType messengerType = KMessengerType.MSN;

        Criteria c = s.createCriteria(KMember.class)
                      .createAlias("messengers", "msg")
                      .add(Restrictions.eq("msg.m_type", messengerType));

        assertEquals(2, c.list().size());
    }

여기까지만 봐서는 둘의 차이가 단순히 alias를 사용해야만 한다는 것 밖에 모르겠습니다.[footnote]'msg.'을 빼고 실행하면 Member에 m_type이란 컬럼이 없다면서  Hibernate.QueryException이 발생합니다.[/footnote]

"MSN 메신저를 가지고 이름이 keesun인 멤버"를 찾으려면 위 주건에 .add(Restriction.eq("name", "keesun")만 추가하면 됩니다. 이것을 맨 끝에 추가 해보면 둘의 차이를 알 수 있습니다.

1. createCriteria() 메소드를 사용.

    public void testCriteriaJoin1(){
        insertDatas();
        final KMessengerType messengerType = KMessengerType.MSN;

        Criteria c = s.createCriteria(KMember.class)
                      .createCriteria("messengers")
                          .add(Restrictions.eq("m_type", messengerType))
                          .add(Restrictions.eq("name", "keesun"));

        assertEquals(1, c.list().size());
    }

=> Messenger에 name이라는 컬럼이 없다면서 HQE[footnote]Hibernate Query Exception[/footnote]가 발생합니다.

2. createAlias() 메소드를 사용.
   

public void testCriteriaJoin2(){
        insertDatas();
        final KMessengerType messengerType = KMessengerType.MSN;

        Criteria c = s.createCriteria(KMember.class)
                      .createAlias("messengers", "msg")
                      .add(Restrictions.eq("msg.m_type", messengerType))
                      .add(Restrictions.eq("name", "keesun"));

        assertEquals(1, c.list().size());
    }

=> 제대로 동작합니다.

createCriteria(String) 메소드 뒤에 붙은 add() 메소드 들은 해당 String 타입에 대항하는 컬럼에 참조하게 되고 createAlias(String, String)메소드 뒤에 붙은 add() 메소드들은 여전히 기본(this)이 상위에 있는 createCriteria(Class)에 있는 Class 타입을 나타냅니다.

1을 제대로 동작하게 하려면 추가한 문장을 s.createCriteria(KMember.class) 요것 바로 다음으로 이동시키면 됩니다.

2에서 좀더 명확하게 나타내려면 .add(Restrictions.eq("this.name", "keesun")); 이렇게 this를 추가해 주면 됩니다.