如何使用hibernate通过包含空值的嵌入式示例进行查询?

时间:2010-03-04 17:38:48

标签: java hibernate nullable

我使用hibernate查询时遇到问题。实体类EntityClass具有类型为embedded的嵌入属性EmbeddedClass,并且此属性具有可为空的属性optional。设置完所有属性后,我可以执行一个非常简单的HQL查询:

Query query = getSession().createQuery(
    "FROM EntityClass t WHERE t.embedded = :embedded");
query.setParameter("embedded", embedded);
return (EntityClass) query.uniqueResult();

但是当属性optional为null时,这不起作用,因为hibernate在SQL中创建了t.optional=?之类的SQL查询,但=NULL应该是IS NULL。 WHERE子句永远不匹配,查询不返回任何行。

进一步的阅读指出了正确处理null的Example。现在我的代码看起来像:

Criteria query = getSession().createCriteria(EntityClass.class);
query.createCriteria("embedded").add(Example.create(embedded));
return (EntityClass) query.uniqueResult();

运行代码时,我得到ClassCastException

java.lang.ClassCastException: EmbeddedClass
    at org.hibernate.criterion.Example.getEntityMode(Example.java:279)
    at org.hibernate.criterion.Example.toSqlString(Example.java:209)
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:357)
    at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:113)
    at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:82)
    at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:91)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1577)
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
    at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:328)

它与EntityPersister.guessEntityMode()返回null有关,因为hibernate会查找实体类的映射,而不是嵌入的映射。

似乎org.hibernate.criterion.Example不能用于嵌入式类。知道如何做到这一点?有没有办法?

这些课程如下:

@Entity
public class EntityClass {
    ...

    @Embedded
    private EmbeddedClass embedded;

    ...
}

@Embeddable
public class EmbeddedClass {
    private String name;
    private String optional;
    ...
}

如果有帮助,我使用hibernate 3.3.1和oracle 10g。

2 个答案:

答案 0 :(得分:2)

呃,我明白了:

调试hibernate代码后,我发现你需要在实体类上构建示例。所以我创建了一个实体的示例实例,设置了嵌入值,并在Example标准中排除了未使用的属性:

Criteria query = getSession().createCriteria(EntityClass.class);
EntityClass example = new EntityClass();
example.setEmbedded(embedded);
query.add(Example.create(example).excludeNone()
    .excludeProperty("id").excludeProperty("other"));
return (EntityClass) query.uniqueResult();

答案 1 :(得分:0)

查看isNull限制条件。我认为它适用于每个会话:

Criteria entityCriteria = getSession().createCriteria(EntityClass.class);
entityCriteria.add(Restrictions.isNull("optional")); // isNull restriction on the optional attribute of your EntityClass
List results = entityCriteria.list();