My company provides developers with days when we can experiment and work on pet projects (a la Google), and I spent some time working with the framework to use the Query Examples, bypassing the restrictions described above. I came up with something that might be useful for other people interested in sample queries. The following is an example structure using an example product.
Criteria criteriaQuery = session.createCriteria(Product.class); Restrictions<Product> restrictions = Restrictions.create(Product.class); Product example = restrictions.getQueryObject(); example.setName(restrictions.like("N%")); example.setPromo("Discounts up to 10%"); restrictions.addRestrictions(criteriaQuery);
Here's an attempt to fix problems in the sample code from the question - the problem of the default value for the "price" field no longer exists, because this structure requires that the criteria be explicitly specified. The second problem related to the inclusion of the enableLike () method is absent - the match is only in the "name" field.
Other issues mentioned in this question have also gone away in this context. Here are implementation examples.
product.setPrice(restrictions.gt(10)); // price > 10 product.setPromo(restrictions.order(false)); // order by promo desc Restrictions<Manufacturer> manufacturerRestrictions = Restrictions.create(Manufacturer.class); //configure manuf restrictions in the same manner... product.setManufacturer(restrictions.join(manufacturerRestrictions)); /* there are also joinSet() and joinList() methods for one-to-many relationships as well */
Even more complex restrictions are available.
product.setPrice(restrictions.between(45,55)); product.setManufacturer(restrictions.fetch(FetchMode.JOIN)); product.setName(restrictions.or("Foo", "Bar"));
After introducing the structure to a colleague, he mentioned that many data display objects have private setters, which makes this type of configuration difficult (another problem with the API example!). So, I also explained it. Instead of using setters, getters can also be requested.
restrictions.is(product.getName()).eq("Foo"); restrictions.is(product.getPrice()).gt(10); restrictions.is(product.getPromo()).order(false);
I also added extra object checking to provide better type safety - for example, do relative criteria (gt, ge, le, lt) all require value? extends Match for a parameter. In addition, if you use a getter in the above style, and there is an @Transient annotation present on the receiver, it will cause a runtime error.
But wait, there still!
If you like that this built-in Hibernate constraint utility can be statically imported so you can do things like criteria.addRestriction (eq ("name", "foo")) without making your code really verbose, there is an option for this also.
Restrictions<Product> restrictions = new Restrictions<Product>(){ public void query(Product queryObject){ queryObject.setPrice(gt(10)); queryObject.setPromo(order(false));
That he is at the moment - many thanks for any feedback! We sent the code to Sourceforge for those who are interested. http://sourceforge.net/projects/hqbe2/