Currently, the org.hibernate.criterion.Example class relies on the following code to determine if any properties contain zeroes:
return object!=null && (
!(object instanceof Number) || ( (Number) object ).longValue()!=0
);
This will trigger a loss of precision with small doubles and floats. For example:
Cat cheapCat = new Cat();
cat.setCost(0.001);
...
Criteria crit = sess.createCriteria(Cat.class);
crit.add( Example.create(cheapCat).excludeZeroes() );
This code will not find any entities whose cost is equal to 0.001. I have attached a patch I used to allow some finer grained control.
Cheers,
Nathan
(Hibernate 3.0.5, jdk1.5.0.04)
----------------------------------- diff from Example.java r1.20 --------------------
--- Example.java 2005-11-17 18:49:13.361823809 -0500
+++ Example.java.bak 2005-11-17 19:20:18.095051296 -0500
@@ -72,17 +72,27 @@
}
}
- static final class NotNullOrZeroPropertySelector implements PropertySelector {
- public boolean include(Object object, String propertyName, Type type) {
- return object!=null && (
- !(object instanceof Number) || ( (Number) object ).longValue()!=0
- );
- }
-
- private Object readResolve() {
- return NOT_NULL_OR_ZERO;
- }
- }
+ static final class NotNullOrZeroPropertySelector implements PropertySelector {
+ public boolean include(Object object, String propertyName, Type type) {
+ if ( object==null || !(object instanceof Number) ) {
+ return false;
+ }
+ if ( !(object instanceof Double) || !(object instanceof Float) ) {
+ return ((Number) object ).longValue()!=0;
+ }
+ if ( object instanceof Double && ( (Double) object ).doubleValue()!=0.0) {
+ return true;
+ }
+ if ( object instanceof Float && ( (Float) object ).floatValue()!=0.0F) {
+ return true;
+ }
+ return true;
+ }
+
+ private Object readResolve() {
+ return NOT_NULL_OR_ZERO;
+ }
+ }
|