[hibernate-dev] Hibernate Disjunction Criteria broken: returns true for empty list of criteria

Darryl Miles darryl-mailinglists at netbauds.net
Wed Oct 29 00:30:47 EDT 2008


William Pugh wrote:
> Generally, when you perform a reduction over an empty list, the
> expected result is the identity element for the reduction. For
> example, the sum of the empty list is 0, the product of the empty list
> is 1, the conjunction of the empty list is true, and the disjunction
> of the empty list is false.
> 
> Hibernate uses "1=1" as the SQL for both Conjunction and Disjunction
> criteria if there is an empty list of criteria.
> 
> Seems to me that this is a bug, although Disjunction isn't documented,
> so who knows what it is "supposed" to do.

Yes the whole point of all WHERE clauses is to filter/reduce the 
available data-set.  I see this point of view but...


In the interest of capturing the most bugs during development by 
incorrect usage (incorrect understanding) of the API, which is the 
easiest thing to spot ?

A dataset returning more data than expected (everything) ?
A dataset returning less data than expected (nothing) ?

My preference goes to returning an extreme state of what you are 
expecting to achieve with the operator.


OR is generally used to increase the size of the returned data-set.  So 
to capture the most bugs we return more data than expected "OR 1=1".


AND is generally used to decrease the size of the returned data-set.  So 
to capture the most bugs we return less data than expected "AND 1=0".


Maybe there is also a case for warning the user when an empty 
Conjunction() and Disjuction() is being used with an option to turn this 
warning off.  I really do think that should be considered a problematic 
programming error.




 From my point of view there is an argument for having either another 
pair of classes or a new API method (my prefered) :

ConjunctionAnulIfEmpty()
DisjunctionAnulIfEmpty()


or with new API method:

Conjunction().setAnulMode(ANUL_IF_EMPTY);
Conjunction().setAnulMode(TRUE_IF_EMPTY);
Conjunction().setAnulMode(FALSE_IF_EMPTY);
Conjunction().setAnulMode(COMPAT_IF_EMPTY);	// Does whatever the 
previous version of HIB did, is also the default

Disjunction().setAnulMode(ANUL_IF_EMPTY);
Disjunction().setAnulMode(TRUE_IF_EMPTY);
Disjunction().setAnulMode(FALSE_IF_EMPTY);
Disjunction().setAnulMode(COMPAT_IF_EMPTY);	// Does whatever the 
previous version of HIB did, is also the default


If setAnulMode() is used in anyway then no warning is ever emitted for 
that statement.


Maybe there should also be API method:

disjunction().isEmpty()
conjunction().isEmpty()

as well as better anul handling.  This is because you have to maintain 
that boolean state yourself in code which again leads to more ugly 
looking code around Critera API use.



This is for Criteria API use cases where you don't want to create a 
temporary Junction, work out if you need it and the attach it to the 
query if you did need it.  You just want Criteria API to ignore it if 
its empty but be able to always attach it to its parent Expression.



Which version if hibernate are you reporting this on ?  There was a 
change at sometime to something in this realm in the release notes.


My $0.02's,

Darryl



More information about the hibernate-dev mailing list