diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractIdMapper.java
index 0472b6ed89..ada602286b 100644
--- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractIdMapper.java
+++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractIdMapper.java
@@ -62,7 +62,7 @@ public abstract class AbstractIdMapper implements IdMapper {
QueryParameterData paramData1 = paramDataIter1.next();
QueryParameterData paramData2 = paramDataIter2.next();
- parametersToUse.addWhere(paramData1.getProperty(prefix1), false, "=", paramData2.getProperty(prefix2), false);
+ parametersToUse.addWhere(paramData1.getProperty(prefix1), false, "=", paramData2.getProperty(prefix2), false);
}
}
@@ -72,7 +72,11 @@ public abstract class AbstractIdMapper implements IdMapper {
Parameters parametersToUse = getParametersToUse(parameters, paramDatas);
for (QueryParameterData paramData : paramDatas) {
- parametersToUse.addWhereWithParam(paramData.getProperty(prefix), equals ? "=" : "<>", paramData.getValue());
+ if (paramData.getValue() == null) {
+ handleNullValue(parametersToUse, paramData.getProperty(prefix), equals);
+ } else {
+ parametersToUse.addWhereWithParam(paramData.getProperty(prefix), equals ? "=" : "<>", paramData.getValue());
+ }
}
}
@@ -85,4 +89,12 @@ public abstract class AbstractIdMapper implements IdMapper {
parametersToUse.addWhereWithNamedParam(paramData.getProperty(prefix), equals ? "=" : "<>", paramData.getQueryParameterName());
}
}
+
+ private void handleNullValue(Parameters parameters, String propertyName, boolean equals) {
+ if (equals) {
+ parameters.addNullRestriction(propertyName, equals);
+ } else {
+ parameters.addNotNullRestriction(propertyName, equals);
+ }
+ }
}
diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotNullAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotNullAuditExpression.java
index 01e50a5917..81aa6f27f6 100644
--- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotNullAuditExpression.java
+++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotNullAuditExpression.java
@@ -25,10 +25,13 @@ package org.hibernate.envers.query.criteria;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.entities.RelationDescription;
+import org.hibernate.envers.entities.mapper.id.QueryParameterData;
import org.hibernate.envers.tools.query.Parameters;
import org.hibernate.envers.tools.query.QueryBuilder;
import org.hibernate.envers.query.property.PropertyNameGetter;
+import java.util.List;
+
/**
* @author Adam Warski (adam at warski dot org)
*/
@@ -44,7 +47,7 @@ public class NotNullAuditExpression implements AuditCriterion {
RelationDescription relatedEntity = CriteriaTools.getRelatedEntity(auditCfg, entityName, propertyName);
if (relatedEntity == null) {
- parameters.addWhereWithParam(propertyName, "<>", null);
+ parameters.addNotNullRestriction(propertyName, true);
} else {
relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, null, propertyName, false);
}
diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NullAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NullAuditExpression.java
index 1aa379324a..078cf14c73 100644
--- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NullAuditExpression.java
+++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NullAuditExpression.java
@@ -44,7 +44,7 @@ public class NullAuditExpression implements AuditCriterion {
RelationDescription relatedEntity = CriteriaTools.getRelatedEntity(auditCfg, entityName, propertyName);
if (relatedEntity == null) {
- parameters.addWhereWithParam(propertyName, "=", null);
+ parameters.addNullRestriction(propertyName, true);
} else {
relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, null, propertyName, true);
}
diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/Parameters.java b/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/Parameters.java
index c39c69c952..1c01e76049 100644
--- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/Parameters.java
+++ b/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/Parameters.java
@@ -116,6 +116,24 @@ public class Parameters {
addWhere(left, true, op, right, true);
}
+ /**
+ * Adds IS NULL
restriction.
+ * @param propertyName Property name.
+ * @param addAlias Positive if alias to property name shall be added.
+ */
+ public void addNullRestriction(String propertyName, boolean addAlias) {
+ addWhere(propertyName, addAlias, "is", "null", false);
+ }
+
+ /**
+ * Adds IS NOT NULL
restriction.
+ * @param propertyName Property name.
+ * @param addAlias Positive if alias to property name shall be added.
+ */
+ public void addNotNullRestriction(String propertyName, boolean addAlias) {
+ addWhere(propertyName, addAlias, "is not", "null", false);
+ }
+
public void addWhere(String left, boolean addAliasLeft, String op, String right, boolean addAliasRight) {
StringBuilder expression = new StringBuilder();
diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/NullPropertyQuery.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/NullPropertyQuery.java
new file mode 100644
index 0000000000..91f9592877
--- /dev/null
+++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/NullPropertyQuery.java
@@ -0,0 +1,103 @@
+package org.hibernate.envers.test.integration.query;
+
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.envers.query.AuditEntity;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.Priority;
+import org.hibernate.envers.test.entities.StrIntTestEntity;
+import org.hibernate.envers.test.entities.ids.EmbId;
+import org.hibernate.envers.test.entities.onetomany.CollectionRefEdEntity;
+import org.hibernate.envers.test.entities.onetomany.CollectionRefIngEntity;
+import org.hibernate.envers.test.entities.onetomany.ids.SetRefEdEmbIdEntity;
+import org.hibernate.envers.test.entities.onetomany.ids.SetRefIngEmbIdEntity;
+import org.junit.Test;
+
+import javax.persistence.EntityManager;
+
+/**
+ * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
+ */
+public class NullPropertyQuery extends AbstractEntityTest {
+ private Integer idSimplePropertyNull = null;
+ private Integer idSimplePropertyNotNull = null;
+ private EmbId idMulticolumnReferenceToParentNull = new EmbId(0, 1);
+ private Integer idReferenceToParentNotNull = 1;
+ private Integer idParent = 1;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(StrIntTestEntity.class);
+ cfg.addAnnotatedClass(SetRefEdEmbIdEntity.class);
+ cfg.addAnnotatedClass(SetRefIngEmbIdEntity.class);
+ cfg.addAnnotatedClass(CollectionRefEdEntity.class);
+ cfg.addAnnotatedClass(CollectionRefIngEntity.class);
+ }
+
+ @Test
+ @Priority(10)
+ public void initData() {
+ // Revision 1
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+ StrIntTestEntity nullSite = new StrIntTestEntity(null, 1);
+ StrIntTestEntity notNullSite = new StrIntTestEntity("data", 2);
+ em.persist(nullSite);
+ em.persist(notNullSite);
+ idSimplePropertyNull = nullSite.getId();
+ idSimplePropertyNotNull = notNullSite.getId();
+ em.getTransaction().commit();
+
+ // Revision 2
+ em.getTransaction().begin();
+ SetRefIngEmbIdEntity nullParentSrieie = new SetRefIngEmbIdEntity(idMulticolumnReferenceToParentNull, "data", null);
+ em.persist(nullParentSrieie);
+ em.getTransaction().commit();
+
+ // Revision 3
+ em.getTransaction().begin();
+ CollectionRefEdEntity parent = new CollectionRefEdEntity(idParent, "data");
+ CollectionRefIngEntity notNullParentCrie = new CollectionRefIngEntity(idReferenceToParentNotNull, "data", parent);
+ em.persist(parent);
+ em.persist(notNullParentCrie);
+ em.getTransaction().commit();
+ }
+
+ @Test
+ public void testSimplePropertyIsNullQuery() {
+ StrIntTestEntity ver = (StrIntTestEntity) getAuditReader().createQuery()
+ .forEntitiesAtRevision(StrIntTestEntity.class, 1)
+ .add(AuditEntity.property("str1").isNull())
+ .getSingleResult();
+
+ assert ver.equals(new StrIntTestEntity(null, 1, idSimplePropertyNull));
+ }
+
+ @Test
+ public void testSimplePropertyIsNotNullQuery() {
+ StrIntTestEntity ver = (StrIntTestEntity) getAuditReader().createQuery()
+ .forEntitiesAtRevision(StrIntTestEntity.class, 1)
+ .add(AuditEntity.property("str1").isNotNull())
+ .getSingleResult();
+
+ assert ver.equals(new StrIntTestEntity("data", 2, idSimplePropertyNotNull));
+ }
+
+ @Test
+ public void testReferenceMulticolumnPropertyIsNullQuery() {
+ SetRefIngEmbIdEntity ver = (SetRefIngEmbIdEntity) getAuditReader().createQuery()
+ .forEntitiesAtRevision(SetRefIngEmbIdEntity.class, 2)
+ .add(AuditEntity.property("reference").isNull())
+ .getSingleResult();
+
+ assert ver.getId().equals(idMulticolumnReferenceToParentNull);
+ }
+
+ @Test
+ public void testReferencePropertyIsNotNullQuery() {
+ CollectionRefIngEntity ver = (CollectionRefIngEntity) getAuditReader().createQuery()
+ .forEntitiesAtRevision(CollectionRefIngEntity.class, 3)
+ .add(AuditEntity.property("reference").isNotNull())
+ .getSingleResult();
+
+ assert ver.getId().equals(idReferenceToParentNotNull);
+ }
+}
\ No newline at end of file