Spring data JPA 使用基于滚动的查询和操作优先级返回意外结果

问题描述 投票:0回答:1

我有这些实体

@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)创建查询); 原因:使用基于字符串的查询不支持滚动查询

这个问题有解决办法吗?

java spring-boot kotlin spring-data-jpa
1个回答
0
投票

问题在于 SQL 中的运算符优先级。这样做的灵魂是以这种方式编写查询(这很丑陋,但它有效)

interface ItemRepository : JpaRepository<Item, Long> {
    fun findByHeadOfIdAndAddedDateNotNullOrHeadOfIdAndDurationNotNull(
        @Param("headOfId1") headOfId1: Long,
        @Param("headOfId1") headOfId2: Long,
        position: ScrollPosition,
        pageable: Pageable,
    ): Window<Item>
}

您也可以使用

Criteria API
来完成此操作。

© www.soinside.com 2019 - 2024. All rights reserved.