首页 > 解决方案 > INSERT 不包含 spring-data-r2dbc 的值

问题描述

当我尝试使用 spring r2dbc 数据插入只有 id 的实体时,出现以下异常:

Exception while fetching data (addChat) : INSERT contains no values

java.lang.IllegalStateException: INSERT contains no values
    at org.springframework.data.r2dbc.core.DefaultStatementMapper.getMappedObject(DefaultStatementMapper.java:159) ~[spring-data-r2dbc-1.0.0.RC1.jar:1.0.0.RC1]
    at org.springframework.data.r2dbc.core.DefaultStatementMapper.getMappedObject(DefaultStatementMapper.java:144) ~[spring-data-r2dbc-1.0.0.RC1.jar:1.0.0.RC1]

数据库postgres:

create table chats
(
    id serial not null
        constraint chats_pkey
            primary key
);

实体

import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Table

@Table("chats")
data class ChatEntity(
        @Id val id: Int? = null
)

存储库:

import org.springframework.data.r2dbc.repository.R2dbcRepository
import org.springframework.stereotype.Repository


@Repository
interface ChatsRepository : R2dbcRepository<ChatEntity, Int>

服务:

//Service
val chatAdded = chatsRepository.save(ChatEntity(id = null)).awaitFirst()

在同一个项目中,我有其他具有 id 和其他列的实体可以正常工作。知道为什么我有这个错误吗?

标签: javaspringpostgresqlr2dbcspring-data-r2dbc

解决方案


我遇到了同样的问题,并且在我实现 org.springframework.data.domain.Persistable<T> 的实体中持续存在,其中 T 是实体 id 类型。

这是我在 kotlin 和协程中实现它的方式。我假设您的上下文配置没问题,并且您正确配置了 org.springframework.r2dbc.core.DatabaseClient

实体:

import org.springframework.data.relational.core.mapping.Table
import org.springframework.data.annotation.*
import org.springframework.data.domain.Persistable
import javax.validation.constraints.NotNull
import javax.validation.constraints.Size

@Table("`authority`")
data class Authority(
        @Id val role: @NotNull @Size(max = 50) String
) : Persistable<String> {
    override fun isNew() = true
    override fun getId() = role
}

道:

import org.springframework.data.repository.kotlin.CoroutineCrudRepository

@Repository("authorityRepository")
interface AuthorityRepository : CoroutineCrudRepository<Authority, String>

功能测试

import kotlinx.coroutines.runBlocking
import kotlin.test.assertEquals
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import Authority
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.r2dbc.core.awaitSingle

@SpringBootTest
class AuthorityRepositoryFuncTest {
    @Autowired
    lateinit var db: DatabaseClient
    @Autowired
    private lateinit var authorityRepository: AuthorityRepository

    suspend fun countAuthority(): Long = db
            .sql("SELECT COUNT(*) FROM `authority`")
            .fetch()
            .awaitSingle()
            .values
            .first() as Long

    @Test
    fun `test save authority`() = runBlocking {
        val countAuthorityBeforeSave = countAuthority()
        val authorityTestValue = "ROLE_TEST"
        authorityRepository.save(Authority(role = authorityTestValue))
        assertEquals(countAuthorityBeforeSave + 1, countAuthority())
    }
}

推荐阅读