Hi,
Hibernate is puzzling me a bit regarding its handling of NULL and "" empty string values.
The Criteria API based following statement:
Code:
Restrictions.ne("course", "")
seems to consider NULL values as "" empty ones.
Indeed I have an entity set up as:
Code:
private String course;
Code:
<property name="course" type="string">
<column name="course" />
</property>
My current Dao implementation does not explicitly consider NULL values:
Code:
public List<ContentImportHistory> findWithCourseContent() {
Criteria criteria = getSession().createCriteria(getPersistentClass());
criteria.add(Restrictions.ne("course", ""))
.addOrder(Order.asc("domainName")).addOrder(Order.desc("importDatetime"));
return criteria.list();
}
And the test works just fine:
Code:
contentImportHistory0 = new ContentImportHistory();
contentImportHistory0.setDomainName(domainName0);
contentImportHistory0.setCourse(course);
DateTime importDatetime = new DateTime();
contentImportHistory0.setImportDatetime(importDatetime);
contentImportHistory0bis = new ContentImportHistory();
contentImportHistory0bis.setDomainName(domainName0);
contentImportHistory0bis.setImportDatetime(importDatetime);
contentImportHistory0bis.setCourse(null);
...
contentImportHistory0 = contentImportHistoryDao.makePersistent(contentImportHistory0);
contentImportHistory0bis = contentImportHistoryDao.makePersistent(contentImportHistory0bis);
...
public void testFindWithCourseContent() {
List<ContentImportHistory> contentImportHistories = contentImportHistoryDao.findWithCourseContent();
assertEquals(1, contentImportHistories.size());
assertEquals(course, contentImportHistories.get(0).getCourse());
}
Clearly, the explicitly set null value in:
Code:
contentImportHistory0bis.setCourse(null);
was not considered to be not equal to "".
Now, if I take another table and another Dao, things seem to be a bit different...
This time the Criteria API based following statement:
Code:
Restrictions.eq("language", "")
seems to NOT consider NULL values as "" empty ones.
Notice the use of eq() instead of the previous ne() method.
Indeed I have an entity set up as:
Code:
private String language;
Code:
<property name="language" type="string">
<column name="language" length="2" />
</property>
This time, my current Dao implementation HAS TO explicitly consider NULL values:
Code:
public NavbarLanguage findByNavbarAndNoLanguage(Navbar navbar) {
Criteria criteria = getSession().createCriteria(getPersistentClass());
criteria.add(Restrictions.eq("navbar", navbar));
criteria.add(Restrictions.or(Restrictions.isNull("language"), Restrictions.eq("language", "")));
return (NavbarLanguage) criteria.uniqueResult();
}
Notice the addition of:
Code:
Restrictions.isNull("language")
And the test works just fine:
Code:
navbar0 = new Navbar();
navbarLanguage0 = new NavbarLanguage();
navbarLanguage0.setLanguage("en");
navbar0.addNavbarLanguage(navbarLanguage0);
navbarLanguage1 = new NavbarLanguage();
navbarLanguage1.setLanguage("fr");
navbar0.addNavbarLanguage(navbarLanguage1);
navbarLanguage2 = new NavbarLanguage();
navbarLanguage2.setLanguage("se");
navbar0.addNavbarLanguage(navbarLanguage2);
navbarLanguage3 = new NavbarLanguage();
navbar0.addNavbarLanguage(navbarLanguage3);
..
navbar0 = navbarDao.makePersistent(navbar0);
..
public void testFindByNavbarAndNoLanguage() {
NavbarLanguage navbarLanguage = navbarLanguageDao.findByNavbarAndNoLanguage(navbar0);
assertEquals(navbarLanguage3.getLanguage(), navbarLanguage.getLanguage());
navbarLanguage3.setLanguage("");
navbarLanguage = navbarLanguageDao.findByNavbarAndNoLanguage(navbar0);
assertEquals(navbarLanguage3.getLanguage(), navbarLanguage.getLanguage());
}
But if the Dao was implemented without the explicit handling of NULL values as in:
Code:
public NavbarLanguage findByNavbarAndNoLanguage(Navbar navbar) {
Criteria criteria = getSession().createCriteria(getPersistentClass());
criteria.add(Restrictions.eq("navbar", navbar));
criteria.add(Restrictions.eq("language", ""));
return (NavbarLanguage) criteria.uniqueResult();
}
then the test would give me the following exception:
Code:
java.lang.NullPointerException
for no entity would be found.
In this case, the NULL value is not considered to be equal to "".
So, to sum this all up, why when doing a ne() is the NULL considered a "" and when doing an eq() the NULL is not considered a "" ?