Hibernate CriteriaBuilder - 如何匹配具有相同字段的所有元素,其中 id 相同

Posted

技术标签:

【中文标题】Hibernate CriteriaBuilder - 如何匹配具有相同字段的所有元素,其中 id 相同【英文标题】:Hibernate CriteriaBuilder - How to match all elements with an equal field where the id is the same 【发布时间】:2014-01-17 04:20:50 【问题描述】:

我正在尝试用 Hibernate 4 做一些有点复杂的事情。

我想使用CriteriaBuilder 导航路径。这是场景

我从用户那里收到一个要匹配的值和一个 TaskField uuid。这些值嵌套在以下内容中: 任务实体具有:

@OneToMany(mappedBy = "task", cascade = CascadeType.ALL)
Collection<TaskFieldValue> taskFieldValues
... Other fields

TaskFieldValue 具有:

@ManyToOne
@JoinColumn(name = "taskfielduuid", referencedColumnName = "uuid", nullable = false)
TaskField taskField

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "TASK_FIELD_VALUE_PIECE")
@AttributeOverride(name="values",column=@Column(name="values", length = 2040))
@OrderColumn
List<String> values
... Other fields

一个TaskField有:

@Id
String uuid

所以我想使用以下条件搜索任务数据库: 我想让所有任务返回它们的 taskField.uuid 值等于用户选择的值 (aka task-&gt;taskFieldValues-&gt;taskField.getUuid().equals(userChosenUuid))

和 -

我只希望任务具有包含在 taskFieldValues (aka task-&gt;taskFieldValues.getValues().contains(value)) 内的值集合中的值。

我想要没有的任务 这是(我认为的)这个谓词的样子:

CriteriaBuilder cb = entityManager.getCriteriaBuilder()
CriteriaQuery<Task> criteria = cb.createQuery(Task.class)
Root<Task> r = criteria.from(Task.class)
Predicate p = cb.and(cb.equal(r.get("taskField.uuid"), fieldName), cb.equal(r.get("taskFieldValues").get("values"), value))

但是,这最终导致了以下异常:

java.lang.IllegalArgumentException: Illegal attempt to dereference path source [null]
org.hibernate.ejb.criteria.path.AbstractPathImpl.illegalDereference(AbstractPathImpl.java:107)
org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:189)
javax.persistence.criteria.Path$get.call(Unknown Source)

在这种情况下是否可以使用另一种方法?我究竟做错了什么?任何见解将不胜感激。

【问题讨论】:

你能再添加一些代码吗 这些似乎都不适用于 Groovy,所以我删除了标签 我在 groovy 中做这一切,因此我放置标签的原因(也许它与问题没有任何关系,但如果你没有,则缺少分号注意到:))。 Ashish,我不太确定还有什么更相关的代码。我添加了一些休眠映射注释以及 CriteriaBuilder 和 Root 的创建。我希望这可以帮助你帮助我.. :) 【参考方案1】:

没关系 - 我想通了。

对于其他有类似问题的人,这是我的解决方案...我创建了一个元模型以使其更容易理解自己。

我必须自己加入集合并引用各个字段:

def taskFieldValues = r.join(Task_.taskFieldValues)
Predicate sameTaskField =    cb.equal(taskFieldValues.get(TaskFieldValue_.taskField).get(TaskField_.uuid), fieldName)
Predicate taskFieldValuesContains = cb.equal(taskFieldValues.join(TaskFieldValue_.values).get("value"), value as char[])
ors.add(cb.and(sameTaskField, taskFieldValuesContains))

【讨论】:

以上是关于Hibernate CriteriaBuilder - 如何匹配具有相同字段的所有元素,其中 id 相同的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate CriteriaBuilder 加入多个表

Hibernate CriteriaBuilder - 如何匹配具有相同字段的所有元素,其中 id 相同

将String传递给String 对于使用Hibernate的CriteriaBuilder.equal方法

Hibernate Criteriabuilder Query with part of a complex id

JPA CriteriaBuilder in条件构建问题

如何告诉 JPA CriteriaBuilder 按返回的唯一数据列排序?