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->taskFieldValues->taskField.getUuid().equals(userChosenUuid))
我只希望任务具有包含在 taskFieldValues
(aka task->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没关系 - 我想通了。
对于其他有类似问题的人,这是我的解决方案...我创建了一个元模型以使其更容易理解自己。
我必须自己加入集合并引用各个字段:
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方法