Thursday, April 28, 2011

Hibernate criteria: Joining table without a mapped association

I'd like to use Hibernate's criteria api to formulate a particular query that joins two entities. Let's say I have two entities, Pet and Owner with a owner having many pets, but crucially that association is not mapped in the Java annotations or xml.

With hql, I could select owners that have a pet called 'fido' by specifying the join in the query (rather than adding a set of pets to the owner class).

Can the same be done using hibernate criteria? If so how?

Thanks, J

From stackoverflow
  • My understanding is that if you do this using HQL, you are creating a Cartesian join with a filter, rather than an inner join. Criteria queries do not support doing this.

    Gareth Davis : David is correct on this, you cannot do this with a Criteria you can do it with HSQL
  • There's a SQLCriterion, which you can give arbitrary SQL, and add to your Criteria. In the SQL string, the token {alias} "will be replaced by the alias of the root entity."

  • In NHibernate you can use subqueries which are defined as DetachedCriteria. Not sure if it works the same in Java, most probably it is the same:

    DetachedCriteria pets = DetachedCriteria.For<Pet>("pet")
      .SetProjection(Projections.Property("pet.ownername"))
      .Add(/* some filters */ );
    
    session.CreateCriteria(typeof(Owner))
      .Add(Subqueries.PropertyIn("name", pets);
    

    Assumed that it is joined using the name of the owner.

  • This is indeed possible with criteria:

    DetachedCriteria ownerCriteria = DetachedCriteria.forClass(Owner.class);
    ownerCriteria.setProjection(Property.forName("id"));
    ownerCriteria.add(Restrictions.eq("ownername", "bob"));
    
    Criteria criteria = getSession().createCriteria(Pet.class);
    criteria.add(Property.forName("ownerId").in(ownerCriteria));
    

0 comments:

Post a Comment