【问题标题】:Spring Data JPA Stream and KotlinSpring Data JPA Stream 和 Kotlin
【发布时间】:2022-01-01 01:46:45
【问题描述】:

我正在尝试在我的 Kotlin 项目中使用 JPA Streams,但我不断收到You're trying to execute a streaming query method without a surrounding transaction that keeps the connection open so that the Stream can actually be consumed. Make sure the code consuming the stream uses @Transactional or any other way of declaring a (read-only) transaction.

我知道使用 Streams 的先决条件,并且我已经用 @Transactional 包围了我的代码并关闭了 Stream 但它不起作用。

这是我的代码:

@Repository
interface MyRepository : JpaRepository<SomeValue, Long> {
    @QueryHints(value = [
        QueryHint(name = HINT_FETCH_SIZE, value = "100"),
        QueryHint(name = HINT_CACHEABLE, value = "false"),
        QueryHint(name = READ_ONLY, value = "true")
    ])
    @Query(
        """select s.id, s.name
            from Some s
            """,
        nativeQuery = true
    )
    fun findSomeValues(
    ): Stream<SomeValue>
}


@Service
class Someservice(
    private val myRepository: MyRepository,
    ...
) {
    @Transactional(readOnly = true)
    fun retrieveSomeValues(
    ): SomeDto {
        
        val someDto =
            myRepository.findSomeValues().use {
                it.map { SomeObject(it.id, it.name) }
                ....
            }

        return someDto
    }
}

编辑:

相关依赖:

Spring Boot: 2.3.4.RELEASE
Kotlin: 1.3.72
Spring-boot-starter-data-jpa

【问题讨论】:

  • @Transactional 仅在类和方法为 public 且非 final 时才有效。
  • 类和方法都是公共的,不是最终的。
  • 我问是因为代码没有使用open 关键字。
  • 我使用的是org.jetbrains.kotlin.plugin.spring,所以它应该在编译时打开所有类。

标签: spring-boot kotlin spring-data-jpa java-stream


【解决方案1】:

您是否有可能最终没有关闭流?您应该尝试以下方法:

@Transactional
void someMethod() {

  try (Stream result = repository.streamAllBy()) {
    // … processing goes here
  }
}

流可能会包装底层数据存储特定的资源 因此,必须在使用后关闭。您可以手动 使用 close() 方法或使用 Java 7 关闭 Stream try-with-resources 块,如下例所示:

【讨论】:

  • 我正在使用 Kotlin 的 use(kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/use.html),它相当于 Java 的 try-with-resources。我也尝试过手动关闭流,但没有奏效。
  • 好吧,我问是因为我不确定 kotlin 的使用,这就是我要求尝试的原因,但是如果你手动关闭它,那么它无论如何也解决不了。您能否添加以下信息:您的相关导入、您如何声明您的存储库、kotlin 版本?
  • 我刚刚添加了这些细节。如果还有其他事情,请告诉我。
  • @zhaider 你试过将@Transactional 添加到类级别而不是函数级别吗?
  • 是的,我已经试过了。
猜你喜欢
  • 2020-01-27
  • 2023-03-13
  • 2020-03-11
  • 2017-11-29
  • 2016-06-03
  • 2020-03-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
相关资源
最近更新 更多