Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Hibernate eqOrIsNull()

I have two rows in MySQL like this

+---------+---------+
| foo     | bar     |
+---------+---------+
|         | NULL    |
|         |         |
+---------+---------+

Where empty are empty strings "".

Now I want to get both of them. I use Criteria and Restrictions.eqOrIsNull() on both columns, but it always returns only one row.

The code is like this

criteria.add(Restrictions.eqOrIsNull("foo", ""));
        .add(Restrictions.eqOrIsNull("bar", ""));

And when I add criteria only on foo, it returns two rows. But for bar, it only returns the second, which is empty.

The javadoc says, Apply an "equal" constraint to the named property. If the value is null, instead apply "is null". So am I getting this wrong, or it should be used in other ways?

UPDATE:
Sorry, I'm so careless. The doc states it clearly. This method works according to the value passed to it, not the actual value of the named property stored in DB.
Source code on Github:

public static Criterion eqOrIsNull(String propertyName, Object value) {
    return value == null
            ? isNull( propertyName )
            : eq( propertyName, value );
}

So in my case, eqOrIsNull returns eq(""). I should have used disjunction of eq and isNull, like Gregory answered.

like image 636
hsluo Avatar asked Oct 11 '13 17:10

hsluo


2 Answers

Apply an "equal" constraint to the named property. If the value is null, instead apply "is null".

This means, is null will be applied only if NULL is passed as the value. If you specify any other string as value, only equal will be applied for that.

This is useful when you're not sure about the actual value being passed at runtime as argument to the parameter value. In such a scenario, in a traditional way, either you need to put a not null check & write criteria based on the not null condition or you need to write criteria in the way mentioned by Gregory's answer.

Keeping all these facts in mind, you should get answer of your question. You're getting only those rows which contain empty value & not the one having NULL value, because you have specified an empty string as 2nd arguement. If you specify NULL as the 2nd arguement, you'll get only those rows having NULL value.

Let me know if that's helpful to you.

like image 179
RAS Avatar answered Sep 28 '22 13:09

RAS


Check if this code does what you want -

criteria.add(Restrictions.or(Restrictions.eq("foo", ""), Restrictions.isNull("foo")))
                .add(Restrictions.or(Restrictions.eq("bar", ""), Restrictions.isNull("bar")));

This snippet uses Hibernate 3.5.0-CR-2 API.

like image 41
Gregory Klimov Avatar answered Sep 28 '22 12:09

Gregory Klimov