4

I'd like to search my data source for all object instances based on the values of an object related by association. The data model can be simplified to: object of type A holds a list of objects of type B. The goal is to find all instances of A where A contains a B such that B has a property value of X.

I can already successfully achieve this using Criteria queries as follows:

  List<A> results = session.createCriteria(A.class)
    .createCriteria("listOfBs")
    .add(Restrictions.eq("propertyInB", x))
    .list();

This is a simplification, and multiple properties of B will apply - the search functionality is necessary for a user populated filter.

I would like to replace this approach with query by example - where I'd simply create an object graph with the desirable parameters. My attempt in following the Hibernate docs failed, and is described in this question.

I thought that it might be helpful to demonstrate what I'm trying to achieve in a manner that works, and then seek equivalents - that's why I'm re-asking the question.

In short, my question is: How would you implement the above Criteria Query as a Query by Example in Hibernate? I'm using Hibernate 3.6.6.

Thanks!

Community
  • 1
  • 1
filip-fku
  • 3,265
  • 1
  • 21
  • 19

1 Answers1

6

Suppose you want to do something like :

Select a.* , b* 
from a join b on a.id = b.id 
where a.property1 = "wwww"
and a.property2="xxxx"
and b.property1="yyyy"
and b.property2="zzzz"

To implement the above query using Query by Example(QBE):

/***Initialize an instance of Class A with the properties that you want to match***/
A instanceA = new A();
instanceA.setProperty1("wwww");
instanceA.setProperty2("xxxx"); 
Example exampleA = Example.create(instanceA);

/***Do the same for the Class B**/
B instanceB = new B();
instanceB.setProperty1("yyyy");
instanceB.setProperty2("zzzz"); 
Example exampleB = Example.create(instanceB);

/**Create and execute the QBE***/
List<A> results = session.createCriteria(A.class)
    .add(exampleA)
    .createCriteria("b",CriteriaSpecification.LEFT_JOIN) // b is the property of Class A
    .add(exampleB)
    .list();

The result is already fetch-joined , which means the collection instance B in the A is already fully initialized.

Ken Chan
  • 84,777
  • 26
  • 143
  • 172
  • Thanks for the answer Ken. I tried this, but ran into the same problems as my previous question (http://stackoverflow.com/questions/7976491/hibernate-query-by-example-involving-one-to-many-relationship) - org.hibernate.QueryException: could not resolve property: _com of B. Would you happen to have any idea what might be going wrong? – filip-fku Nov 23 '11 at 23:47
  • I have no idea now . Normally , if you write some invalid path in the code , such as `.createCriteria("_com",CriteriaSpecification.LEFT_JOIN)` , and `_com` is not the property of your entity ,then `could not resolve property` will occur. – Ken Chan Nov 24 '11 at 02:20
  • Unfortunately _com is not a property/field I have defined anywhere and this does not work for me. Further, _com is not a property name that exists in any of the libraries included in my workspace.. This is however what the doc suggests we do for QBE, so I'll mark this as the answer.. I'll have to go without QBE it seems. – filip-fku Nov 28 '11 at 00:00