【发布时间】:2021-06-17 13:37:32
【问题描述】:
我有两个班:
@Entity
@Table(name = "foo")
data class Foo {
@Id
val id: UUID
// a lot more values
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "foo_bar", joinColumns = [JoinColumn(name = "foo_bar_id")])
val bars: Set<FooBar>?
}
data class FooBar {
val fooBarId: UUID
val bar: Bar
val validUntil: Instant
}
目前,我使用 Predicate 和 CriteriaBuilder 在此实体上拥有广泛的搜索功能。我希望能够在我们的搜索中仅包含 Foo 对象,这些对象在其 FooBar JoinColumn 行中具有特定 Bar 值,并且如果 none 的 joinColumn 行具有该特定 Bar 则仅返回 FooBar 对象的函数价值。
我现在拥有的是:
fun searchPaged(
// numerous criteria values
flipFilterOnBar: Boolean?,
bar: Bar?,
pageable: Pageable
): Page<Foo> {
return findAll({ root, _, cb ->
val predicates = mutableListOf<Predicate>(
cb.or(
//some criteria
)
)
//more criteria
//
//
if (bar != null) {
val joinColumn: Join<Foo, FooBar> = root.join<Foo?, FooBar?>("bars", JoinType.INNER)
if (flipFilterOnBar == true) { //Nullable boolean
// this part makes the query return a row for each join column and filters out only the filtered value (returning more rows than if this clauses was not added.
predicates.add(
cb.notEqual(joinColumn.get<Bar>("bar"), bar)
)
} else {
predicates.add(
cb.equal(joinColumn.get<Bar>("bar"), bar)
)
}
}
cb.and(*predicates.toTypedArray())
}, pageable)
我想知道如何在此处使用标准构建器仅在 FooBar 行都不包含指定的 Bar 值时返回 Bar 实体。我现在编写它的方式将所有 Foo 和 FooBar 行连接在一起,并且只过滤具有指定 Bar 值的组合行,返回另一个不是我想要的组合行。
例如,如果我有一个包含 3 个 FooBar 的 Foo,并且我想过滤掉所有 Foo 的 Bar 值为“b”。查询检索此 Foo 3 次(每个 Bar 元素一次),并且仅过滤其中包含 Foo 且值为“b”的组合行。返回其他两行。我希望查询不返回任何这些行,因为其中一行包含值“b”。
【问题讨论】:
标签: java kotlin jpa orm criteria