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