我如何查询Hibernate的对象,其中属性可能为空或特定值? [英] How do I query Hibernate for object where property may be null or specific value?

查看:640
本文介绍了我如何查询Hibernate的对象,其中属性可能为空或特定值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理以下对象:

RawRead
RawRead.Checkpoint



Checkpoint.EndCustomer

Guard

其中,Checkpoint和Guard属于RawRead的属性,EndCustomer是检查点。






我目前的Hibernate gubbins:

  Criteria crit = sess.createCriteria(RawRead.class); 
crit.add(
Restrictions.or(
Restrictions.eq(checkpoint,null),
Restrictions.in(checkpoint.parentEndCustomer,collectionOfEndCustomers)

);

所以Checkpoint可以为null,但如果它在那里,我只想要RawRead对象所在的父EndCustomer对象是在checkpoint.parentEndCustomer属性。



我希望这是有道理的。






我上面的猜测产生了一个错误,(对我而言)表明我的标准被错误地指定:

  [请求处理失败;嵌套的异常是org.hibernate.QueryException:无法解析带有根本原因的属性:checkpoint.parentEndCustomer:uk.co.romar.guardian.objects.RawRead] org.hibernate.QueryException:
无法解析属性:checkpoint .parentEndCustomer:
中的uk.co.romar.guardian.objects.RawRead org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:81)at
org.hibernate.persister.entity .AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:96)at
org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:62)at
org.hibernate.persister.entity.AbstractEntityPersister.toColumns (AbstractEntityPersister.java:1457)at
org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:483)

RawRead的相关部分:

  @ManyToOne 
@JoinColumn(name = CHECKPOINT_OID)
@No tFound(action = NotFoundAction.IGNORE)
public Checkpoint checkpoint = null;
public void setCheckCheck(Checkpoint in){this.checkpoint = in;}
public Checkpoint getCheckpoint(){return this.checkpoint;}

@ManyToOne
@ JoinColumn(name =GUARD_OID)
@NotFound(action = NotFoundAction.IGNORE)
private Guard guard = null;
public void setGuard(Guard in){this.guard = in;}
public Guard getGuard(){return this.guard;}

从检查点开始:

  @ManyToOne 
@JoinColumn (name =ENDCUSTOMER_OID)
@NotFound(action = NotFoundAction.IGNORE)
private EndCustomer parentEndCustomer = null;
public EndCustomer getParentEndCustomer(){return this.parentEndCustomer;}
public void setParentEndCustomer(EndCustomer ownerCustomer){this.parentEndCustomer = ownerCustomer;}

$ b


编辑遵循下面的第一个答案。



如果我在数据库中有一些这样的数据(我希望符号很有意义):

  RawRead {
ID = 1
checkpoint = {id = 1,parentEndCustomer = {ID = 1}}
}
RawRead {
ID = 2
checkpoint = {id = 4, parentEndCustomer = {ID = 4}}
}
RawRead {
ID = 3
checkpoint = {id = 7,parentEndCustomer = {ID = 31}}
}
RawRead {
ID = 4
checkpoint = {null}
}

以及在限制中给出的collectionOfEndCustomers是这样的:
EndCustomer = {ID = 31}

我想检索RawReads只有3和4。 RawRead 1& 2被拒绝,因为子检查点属性的parentEndCustomer与传入collectionOfEndCustomers中的限制的不匹配。



应选择RawRead.3,因为parentEndCustomer匹配传入的集合中的一个。应选择RawRead.4,因为检查点为空。



根据以下第一个答案中的指导,将导致所有上述RawReads而不是我之后的子集。

解决方案

你不能像HQL那样链接属性。您必须使用连接和Criteria。由于检查点可以为空,所以您必须使用左连接。而且, Restrictions.eq()不能用于和 null 进行比较(就像在HQL和SQL中一样) 。您必须使用 Restrictions.isNull()来做到这一点。



所以你的查询应该如下所示: p>

  Criteria crit = sess.createCriteria(RawRead.class,rawRead); 
crit.createAlias(rawRead.checkpoint,checkpoint,Criteria.LEFT_JOIN)
crit.add(
Restrictions.or(
Restrictions.isNull(checkpoint.id ),
Restrictions.in(checkpoint.parentEndCustomer,collectionOfEndCustomers)

);


I have the following objects I'm working with:

RawRead RawRead.Checkpoint

Checkpoint.EndCustomer

Guard

Where Checkpoint and Guard are properties of RawRead, EndCustomer is a property of Checkpoint. All are objects.


My current Hibernate gubbins:

Criteria crit = sess.createCriteria(RawRead.class);
crit.add(
  Restrictions.or(
    Restrictions.eq("checkpoint", null),
    Restrictions.in("checkpoint.parentEndCustomer",collectionOfEndCustomers)
  )
);

So Checkpoint can be null, but if it is there I only want the RawRead objects where the parentEndCustomer object is in the checkpoint.parentEndCustomer property.

I hope that makes sense.


My guesstimate above produces an error that (to me) suggests that my criteria are incorrectly specified:

[Request processing failed; nested exception is org.hibernate.QueryException: could not resolve property: checkpoint.parentEndCustomer of: uk.co.romar.guardian.objects.RawRead] with root cause org.hibernate.QueryException: 
could not resolve property: checkpoint.parentEndCustomer of: uk.co.romar.guardian.objects.RawRead at 
org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:81) at 
org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:96)   at  
org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:62) at 
org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1457) at 
org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:483)

Relevant bits of RawRead:

@ManyToOne
@JoinColumn(name="CHECKPOINT_OID")
@NotFound(action=NotFoundAction.IGNORE)
public Checkpoint checkpoint = null;
public void setCheckpoint(Checkpoint in) {this.checkpoint = in;}
public Checkpoint getCheckpoint() {return this.checkpoint;}

@ManyToOne
@JoinColumn(name="GUARD_OID")
@NotFound(action=NotFoundAction.IGNORE)
private Guard guard = null;
public void setGuard(Guard in) {this.guard = in;}
public Guard getGuard() {return this.guard;}

And from Checkpoint:

    @ManyToOne
@JoinColumn(name="ENDCUSTOMER_OID")
@NotFound(action=NotFoundAction.IGNORE)
private EndCustomer parentEndCustomer = null;
public EndCustomer getParentEndCustomer() {return this.parentEndCustomer;}
public void setParentEndCustomer(EndCustomer ownerCustomer) {this.parentEndCustomer = ownerCustomer;}


EDIT Follows after implementing first answer from below.

If I have some data like this in the database (I hope the notation makes sense!):

RawRead {
 ID=1
 checkpoint={id=1,parentEndCustomer={ID=1}}
}
RawRead {
 ID=2
 checkpoint={id=4,parentEndCustomer={ID=4}}
}
RawRead {
 ID=3
 checkpoint={id=7,parentEndCustomer={ID=31}}
}
RawRead {
 ID=4
 checkpoint={null}
}

and the collectionOfEndCustomers given in the Restriction is like this: EndCustomer={ID=31}

The I would want to retrieve RawReads 3 and 4 only. RawRead 1 & 2 are rejected because the parentEndCustomer of the child checkpoint property does't match the one passed in to the restriction in collectionOfEndCustomers.

RawRead.3 is should be selected because the parentEndCustomer matches one in the collection passed in. RawRead.4 should be selected because the checkpoint is null.

Following the guidance in the first answer below results in all of the above RawReads being returned rather than the subset I'm after.

解决方案

You can't chain properties like you would do in HQL. You must use joins, with Criteria. And since checkpoint can be null, you must use a left join. Moreover, Restrictions.eq() can't be used to compare something with null (as in HQL and SQL). You must use Restrictions.isNull() to do that.

So your query should look like this:

Criteria crit = sess.createCriteria(RawRead.class, "rawRead");
crit.createAlias("rawRead.checkpoint", "checkpoint", Criteria.LEFT_JOIN)
crit.add(
    Restrictions.or(
        Restrictions.isNull("checkpoint.id"),
        Restrictions.in("checkpoint.parentEndCustomer", collectionOfEndCustomers)
    )
);

这篇关于我如何查询Hibernate的对象,其中属性可能为空或特定值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆