I did not want to use "excludeNone()" as I wanted null properties to be ignored. In the end, I used the introspection workaround. For anyone who's interested:
Code:
public <T extends BaseEntity> List<T> listByExample (T example)
{
/*
return listByCriteria ((Class<T>) example.getClass(),
Example.create (example)
.ignoreCase()
.enableLike ()) ;
*/
Class<T> clazz = (Class<T>) example.getClass() ;
Criteria crit = getSession().createCriteria (clazz) ;
crit.add (Example.create (example).ignoreCase().enableLike()) ;
PropertyDescriptor [] pds = PropertyUtils.getPropertyDescriptors (example) ;
for (PropertyDescriptor pd : pds) {
Class<?> propertyClass = pd.getPropertyType () ;
if (BaseEntity.class.isAssignableFrom (propertyClass)) {
String propertyName = pd.getName () ;
if (log.isDebugEnabled ())
log.debug ("Found property '" + propertyName + "' of type " + propertyClass.getName ()) ;
BaseEntity foreignEntity = null ;
try {
foreignEntity = (BaseEntity) PropertyUtils.getProperty (example, propertyName) ;
}
catch (Exception e) {
log.error (e) ;
}
if (foreignEntity != null) {
Serializable foreignId = foreignEntity.getId () ;
if (foreignId != null) {
// create sub-criteria based on id
crit.createCriteria (propertyName)
.add (Restrictions.idEq (foreignId)) ;
}
else {
// create sub-criteria based on matching properties
crit.createCriteria (propertyName)
.add (Example.create (foreignEntity).ignoreCase().enableLike()) ;
}
}
}
}
return crit.list () ;
}