“Value is never used as Publisher”的中文翻译是:”值从未被用作发布者”。

huangapple go评论90阅读模式
英文:

"Value is never used as Publisher"

问题

我目前正在开发一个Spring Boot项目。我已经连接到了Couchbase,并想要向其upsert一个文档。在我的存储库层中,我使用了upsert()方法。以下是我的存储库层代码:

import com.couchbase.client.java.ReactiveCluster
import com.couchbase.client.java.ReactiveCollection
import com.trendyol.productstockapi.entity.ProductStock
import org.springframework.stereotype.Repository

@Repository
class ProductStockRepository (
    private val cluster: ReactiveCluster,
    private val productStockCollection: ReactiveCollection
){

    fun upsertProductStock(productStock: ProductStock){
        val result = productStockCollection.upsert(
            productStock.stockId,
            productStock
        )
    }

    fun deleteProductStock(productStockId: String) {
        val result = productStockCollection.remove(productStockId)
    }

}

以下是Couchbase的配置:

import com.couchbase.client.core.cnc.tracing.NoopRequestTracer
import com.couchbase.client.core.env.CompressionConfig
import com.couchbase.client.core.env.IoEnvironment
import com.couchbase.client.core.env.OrphanReporterConfig
import com.couchbase.client.core.env.TimeoutConfig
import com.couchbase.client.java.ClusterOptions
import com.couchbase.client.java.ReactiveCluster
import com.couchbase.client.java.ReactiveCollection
import com.couchbase.client.java.codec.JacksonJsonSerializer
import com.couchbase.client.java.env.ClusterEnvironment
import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.time.Duration

@Configuration
@EnableConfigurationProperties(CouchbaseConfigurationProperties::class)
class CouchbaseConfiguration(
    private val couchbaseConfigurationProperties: CouchbaseConfigurationProperties,
    private val objectMapper: ObjectMapper?,
) {

    @Bean
    fun clusterEnvironment(): ClusterEnvironment {
        return ClusterEnvironment
            .builder()
            .jsonSerializer(JacksonJsonSerializer.create(objectMapper))
            .ioEnvironment(IoEnvironment.builder().eventLoopThreadCount(Runtime.getRuntime().availableProcessors()))
            .compressionConfig(CompressionConfig.builder().enable(true))
            .requestTracer(NoopRequestTracer.INSTANCE)
            .orphanReporterConfig(OrphanReporterConfig.builder().emitInterval(Duration.ofSeconds(60)))
            .timeoutConfig(
                TimeoutConfig.builder()
                    .kvTimeout(couchbaseConfigurationProperties.connection.kvTimeout)
                    .connectTimeout(couchbaseConfigurationProperties.connection.connectTimeout)
                    .queryTimeout(couchbaseConfigurationProperties.connection.queryTimeout)
            )
            .build()
    }

    @Bean
    fun cluster(clusterEnvironment: ClusterEnvironment): ReactiveCluster {
        val clusterOptions = ClusterOptions
            .clusterOptions(couchbaseConfigurationProperties.secrets.cbUsername, couchbaseConfigurationProperties.secrets.cbPassword)
            .environment(clusterEnvironment)

        return ReactiveCluster.connect(couchbaseConfigurationProperties.hosts.joinToString(","), clusterOptions)
    }

    @Bean
    fun productStockCollection(cluster: ReactiveCluster): ReactiveCollection {
        return cluster.bucket(couchbaseConfigurationProperties.productContentBucket).collection("stock")
    }
}

问题是,当我悬停在upsert()或remove()方法上时,我会收到一个警告,指示:

Value is never used as Publisher

我的Couchbase版本是

com.couchbase.client:java-client:3.2.4

我还没有找到任何解决方法。

英文:

I am currently working on a Spring Boot project. I have connected to a Couchbase, and want to upsert a document to the it. In my repository layer I make use of the upsert() method. Following is my repository layer:

import com.couchbase.client.java.ReactiveCluster
import com.couchbase.client.java.ReactiveCollection
import com.trendyol.productstockapi.entity.ProductStock
import org.springframework.stereotype.Repository

@Repository
class ProductStockRepository (
    private val cluster: ReactiveCluster,
    private val productStockCollection: ReactiveCollection
){

    fun upsertProductStock(productStock: ProductStock){
        val result = productStockCollection.upsert(
            productStock.stockId,
            productStock
        )
    }

    fun deleteProductStock(productStockId: String) {
        val result = productStockCollection.remove(productStockId)
    }

}

The following is the Couchbase configurations:

import com.couchbase.client.core.cnc.tracing.NoopRequestTracer
import com.couchbase.client.core.env.CompressionConfig
import com.couchbase.client.core.env.IoEnvironment
import com.couchbase.client.core.env.OrphanReporterConfig
import com.couchbase.client.core.env.TimeoutConfig
import com.couchbase.client.java.ClusterOptions
import com.couchbase.client.java.ReactiveCluster
import com.couchbase.client.java.ReactiveCollection
import com.couchbase.client.java.codec.JacksonJsonSerializer
import com.couchbase.client.java.env.ClusterEnvironment
import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.time.Duration

@Configuration
@EnableConfigurationProperties(CouchbaseConfigurationProperties::class)
class CouchbaseConfiguration(
    private val couchbaseConfigurationProperties: CouchbaseConfigurationProperties,
    private val objectMapper: ObjectMapper?,
) {

    @Bean
    fun clusterEnvironment(): ClusterEnvironment {
        return ClusterEnvironment
            .builder()
            .jsonSerializer(JacksonJsonSerializer.create(objectMapper))
            .ioEnvironment(IoEnvironment.builder().eventLoopThreadCount(Runtime.getRuntime().availableProcessors()))
            .compressionConfig(CompressionConfig.builder().enable(true))
            .requestTracer(NoopRequestTracer.INSTANCE)
            .orphanReporterConfig(OrphanReporterConfig.builder().emitInterval(Duration.ofSeconds(60)))
            .timeoutConfig(
                TimeoutConfig.builder()
                    .kvTimeout(couchbaseConfigurationProperties.connection.kvTimeout)
                    .connectTimeout(couchbaseConfigurationProperties.connection.connectTimeout)
                    .queryTimeout(couchbaseConfigurationProperties.connection.queryTimeout)
            )
            .build()
    }

    @Bean
    fun cluster(clusterEnvironment: ClusterEnvironment): ReactiveCluster {
        val clusterOptions = ClusterOptions
            .clusterOptions(couchbaseConfigurationProperties.secrets.cbUsername, couchbaseConfigurationProperties.secrets.cbPassword)
            .environment(clusterEnvironment)

        return ReactiveCluster.connect(couchbaseConfigurationProperties.hosts.joinToString(","), clusterOptions)
    }

    @Bean
    fun productStockCollection(cluster: ReactiveCluster): ReactiveCollection {
        return cluster.bucket(couchbaseConfigurationProperties.productContentBucket).collection("stock")

    }


}

The problem is when I hover on the upsert() or remove() methods, I get a warning stating

Value is never used as Publisher

My Couchbase version is
com.couchbase.client:java-client:3.2.4

I haven't been able to come up with any solution.

答案1

得分: 3

ReactiveCollection.upsert() 返回一个 Mono。在发生任何操作之前,您需要订阅这个 Mono。IntelliJ 警告您没有订阅这个 Mono(它是一种 Publisher 类型)。

让您的代码能够运行的最简单方法是调用 Mono.block(),它会订阅 Mono 并阻塞当前线程,直到 Mono 发出一个值:

fun upsertProductStock(productStock: ProductStock){
    val result = productStockCollection.upsert(
        productStock.stockId,
        productStock
    ).block()
}

然而,像这样阻塞线程是不高效的。(如果您愿意阻塞当前线程,您可能会考虑使用 Couchbase SDK 的阻塞 API 而不是其响应式 API。)由于您正在使用 Kotlin,您可以将 upsertProductStock 改为挂起函数,在 Mono 执行其工作时挂起而不是阻塞。

为了使用这个技巧,您需要将 kotlinx-coroutines-reactive 添加为项目的依赖项:

<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-coroutines-reactive</artifactId>
    <version>${kotlin.coroutines.version}</version>
</dependency>

然后您可以编写:

suspend fun upsertProductStock(productStock: ProductStock) {
    productStockCollection.upsert(
        productStock.stockId,
        productStock
    ).awaitSingle()
}

最后,除非您有某种原因需要使用 Couchbase Java SDK(比如您使用 Spring Data Couchbase 并希望共享相同的连接),考虑使用 Couchbase Kotlin SDK 而不是 Java SDK。Couchbase Kotlin SDK 的函数自然是挂起函数。使用 Kotlin SDK,您可以这样编写:

suspend fun upsertProductStock(productStock: ProductStock) {
    // 在 Kotlin SDK 中,`upsert` 是一个挂起函数
    productStockCollection.upsert(
        productStock.stockId,
        productStock
    )
}
英文:

ReactiveCollection.upsert() returns a Mono. You'll need to subscribe to the Mono before anything happens. IntelliJ is warning you that you're not subscribing to the Mono (which is a type of Publisher).

The simplest way to get your code working is to call Mono.block(), which subscribes to the Mono, and blocks the current thread until the Mono emits a value:

fun upsertProductStock(productStock: ProductStock){
    val result = productStockCollection.upsert(
        productStock.stockId,
        productStock
    ).block()
}

However, blocking like this is not efficient. (If you're willing to block the current thread, you might as well use the Couchbase SDK's blocking API instead of its reactive API.) Since you're using Kotlin, you can turn upsertProductStock into a suspend function, and suspend instead of blocking while the Mono does its work.

For this trick, you'll need to add kotlinx-coroutines-reactive as a dependency of your project.

&lt;dependency&gt;
    &lt;groupId&gt;org.jetbrains.kotlinx&lt;/groupId&gt;
    &lt;artifactId&gt;kotlinx-coroutines-reactive&lt;/artifactId&gt;
    &lt;version&gt;${kotlin.coroutines.version}&lt;/version&gt;
&lt;/dependency&gt;

Then you can write:

suspend fun upsertProductStock(productStock: ProductStock) {
    productStockCollection.upsert(
        productStock.stockId,
        productStock
    ).awaitSingle()
}

Finally, unless you need to use the Couchbase Java SDK for some reason (like maybe you're using Spring Data Couchbase and want to share the same connection), consider using the Couchbase Kotlin SDK instead of the Java SDK. The functions of the Couchbase Kotlin SDK are naturally suspend functions. With the Kotlin SDK, you would write:

suspend fun upsertProductStock(productStock: ProductStock) {
    // In the Kotlin SDK, `upsert` is a suspend function
    productStockCollection.upsert(
        productStock.stockId,
        productStock
    )
}

huangapple
  • 本文由 发表于 2023年7月20日 21:41:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76730509.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定