Wednesday, January 06, 2010

Hibernate3 Tip#6: QL Parameters Are Objects

Consider an entity User that has a many-to-one reference to a Role entity. Each of these entities has an identifier field used to uniquely identify objects. The database schema would be such that the Users table has a column (usually of a numeric data type) with a foreign key constraint to a Role. Supposing you wanted to get all users with a specific role, plain SQL allows querying with a "where user.roleid=?" and providing a numeric type that matches the role's identifier type.

In Hibernate, however, this strategy fails with a "org.hibernate.PropertyAccessViolation: could not get a field value by reflection" exception. Hibernate expects you to provide actual objects as parameters. Thus the QL for the above scenario would require you to find the persistent Role object first, then pass it (or its proxy given by getReference()) as a parameter. Alternatively, you may choose to use native SQL queries. You may consider this a side effect of using an object-oriented persistent layer and query language. It is particularly useful in resolving object identity issues where perhaps more than one property is used to define the object's primary key.