我有这些实体
@Entity
@Table(name = "Item")
class Item(
@Column(name = "name", nullable = false)
var name: String,
@Column(name = "added_date", columnDefinition = "TIMESTAMP WITH TIME ZONE", nullable = true)
var addedDate: ZonedDateTime? = null,
@Column(name = "duration", nullable = true)
var duration: Int? = null,
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "head_of_id", nullable = false)
val headOf: HeadOf,
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0
}
@Entity
@Table(name = "head_of")
class HeadOf(
@Column(name = "company", nullable = false)
var company: String,
@Column(name = "city", nullable = false)
var city: String,
@Column(name = "age", nullable = true)
var age: Int?
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0
}
这是对应的存储库
interface ItemRepository : JpaRepository<Item, Long> {
fun findByHeadOfIdAndAddedDateNotNullOrDurationNotNull(
headOfId: Long,
position: ScrollPosition,
pageable: Pageable,
): Window<Item>
}
这就是表中当前的内容
Item
。它是一行(它是 dump
的结果)
INSERT INTO public.item VALUES (1, 'Some fancy title', '2024-12-31 07:14:42.955789+00', NULL, 1000);
如您所见,
headOf
是 1000L
。
现在,当我使用以下值调用此函数时
findByHeadOfIdAndAddedDateNotNullOrDurationNotNull
头ID:0 滚动位置:滚动位置.of(...) PageRequest.of(0, 10)
它返回我其中的一行。我不希望这样,因为我传递的
headOfId
是 0L
而不是 1000L
。
这是执行的请求
SELECT
i1_0.id,
i1_0.added_date,
i1_0.duration,
i1_0.head_of_id,
FROM
item i1_0
LEFT JOIN
headOf h1_0
ON
h1_0.id = i1_0.head_of_id
WHERE
h1_0.id = ?
AND (i1_0.added_date IS NOT NULL OR i1_0.duration IS NOT NULL)
OFFSET
? ROWS
FETCH FIRST
? ROWS ONLY;
我无法使用
@Query
注释,然后我得到了这个
无法为公共抽象org.springframework.data.domain.Window org...jpa.repository.ItemRepository.findByHeadOfIdAndAddedDateNotNullOrDurationNotNull(long,org.springframework.data.domain.ScrollPosition,org.springframework.data.domain.Pageable)创建查询); 原因:使用基于字符串的查询不支持滚动查询
这个问题有解决办法吗?
问题在于 SQL 中的运算符优先级。这样做的灵魂是以这种方式编写查询(这很丑陋,但它有效)
interface ItemRepository : JpaRepository<Item, Long> {
fun findByHeadOfIdAndAddedDateNotNullOrHeadOfIdAndDurationNotNull(
@Param("headOfId1") headOfId1: Long,
@Param("headOfId1") headOfId2: Long,
position: ScrollPosition,
pageable: Pageable,
): Window<Item>
}
您也可以使用
Criteria API
来完成此操作。