I'd like to use @Where
annotation in Hibernate to remove objects which have been marked 'deleted' by a boolean property on that object. For example the following should prevent any deleted addresses from being loaded by Hibernate:
@OneToMany(mappedBy="contact")
@Where(clause="deleted=FALSE")
private Set<Address> addresses;
However when I use a clause like deleted=FALSE
then Hibernate will mangle the boolean literal by prefixing it with a table name, which causes the query to fail. For example:
select ... from address address0_ where ( address0_.deleted=address0_.FALSE) and address0_.contact_id=?
What I expected is something like (address0_.deleted=FALSE)
instead of (address0_.deleted=address0_.FALSE)
.
Is there a way to specify the @Where clause or configure Hibernate to correctly output the boolean value?
PS. Note that it is possible with some databases to specify the boolean value as a string literal like this:
@Where(clause="deleted='FALSE'")
That will get converted to (address0_.deleted='FALSE')
which works just fine in, for example, PostgreSQL. However I am using HSQLDB for this project, and HSQLDB does not seem to support boolean string literals. On HSQL I get the following exception when using deleted='FALSE'
:
org.hsqldb.HsqlException: data exception: invalid character value for cast
I've discovered bug reports about this which have been unresolved for more than six years! The Hibernate issue tracker has HHH-1587, HHH-2775 and ANN-647 on the problem.
The solution is to create a custom Dialect class which registers true
, false
and unknown
as keywords (these are the official boolean literals in the SQL spec). This causes Hibernate to recognise them as keywords and thus stop prefixing them as if they were columns.
Here's my custom Dialect class which solved the problem for me:
public class ImprovedHSQLDialect extends HSQLDialect {
public ImprovedHSQLDialect() {
super();
registerKeyword("true");
registerKeyword("false");
registerKeyword("unknown");
}
}
Once this dialect is in use, @Where(clause="deleted=FALSE")
works correctly.
When the column is created as BOOLEAN in the table defintion, the latest HSQLDB supports WHERE active = TRUE
, WHERE active = 'TRUE'
as well as WHERE active
.
Hibernate may be creating a BIT column, in which case WHERE active = TRUE
, WHERE active = B'1'
or WHERE active = 1
will work.
Please use version 2.2.8 or greater for these capabilities.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With