tags:

views:

18

answers:

1

I trying to build a Criteria made up of various components. Imagine the mapped classes below.

class Thing {
   Inner inner;
   String x;
}

class User {
    Id; // mapped as id.
    String first; // indexed columns etc
    String last;
}

I would like to create a query (aka Criterion) for Things where User.first=@1 and User.last=@2. I can easily achieve this by creating sub criteria off the root for the User and then adding the Restrictions to this.

Critera root = ...
root.add( Restrictions.eq( "xxx", @2 ));

Criteria user = root.createCritera("user");
user.add( Restrictions.eq("first", @1));
...etc

However i cannot create an AND for a property of thing and user using code similar to ...

Critera root = ...
root.add( Restrictions.and( Restrictions.eq("user.first", @1), Restrictions.eq("thing.x", @2));

A QueryException is thrown that "user.first" is not an association. The need to manually create criteria before adding the restriction seems something that should not be necessary but yet it is.. Attempts to use alias in the second form also fail.

A: 

Do users have a list of things? or do things have a list of users?

the example below states users have a list of things.

Criteria user = root.createCritera("User");
user.add( Restrictions.eq("first", @1));
user.createAlias('usersSetOfThings','userThings', Criteria.INNER_JOIN );
user.add(Restrictions.eq('userThings.x', @2));
user.list();

these mappings will make the above code run:

    <class name='User' table='your user table name'>
      <id name='id' column='ID' type='long'/>
      <property name='first' column='FIRST' type='string'/>
      <property last='last' column='LAST' type='string'/>
      <set name='usersSetOfThings' table='what_did_you_do_to_link_them_in_the_DB?'>
      <key column='id'/>
      <one-to-many column='whatever_you_did.user_id_fk_column_name' class='full.package.name.Thing'/>
     </set>
    </class>

<class name='thing' table='your things table name'>
      <many-to-one name="Inner" class="full.package.name.Inner"
                fetch="select">
                <column name="inner_FK"/>
      </many-to-one>
      <property name='x' type='string'/>

    </class>
DefyGravity