'Spring Data R2dbc UUID @Id Persistable
I am not sure whether this is a bug or I am using Persistable incorrectly. Aim: make the UserId non-null to avoid having to assert non-null when using in the code
User.kt
@Table(value = "main.user")
data class User(
@Id
@Column("id")
var userId: UUID = UUID(0,0),
val username: Username,
val isVerified: Boolean = false,
val updated: LocalDateTime,
val updatedBy: String
) : Persistable<UUID> {
override fun isNew(): Boolean = userId.equals(UUID(0,0))
override fun getId(): UUID = userId
}
UserRepository.kt
@Repository
interface UserModelRepository : CoroutineCrudRepository<User, UUID>
Test.kt
@DataR2dbcTest
internal class Test {
@Autowired
private lateinit var userModelRepository: UserModelRepository
@Test
fun `should save the user model`() = runBlocking {
val userModel = createUserModel()
val actual = UserModelRepository.save(userModel)
actual.userId shouldNotBe UUID(0, 0)
}
}
SQL
CREATE TABLE IF NOT EXISTS main.user
(
id UUID NOT NULL PRIMARY KEY DEFAULT GEN_RANDOM_UUID(),
username CHARACTER VARYING(70) NOT NULL UNIQUE,
is_verified BOOLEAN NOT NULL,
updated TIMESTAMP WITHOUT TIME ZONE NOT NULL,
updated_by CHARACTER VARYING(255) NOT NULL
);
Expected: The test to pass as the Id should be generated by the database Actual: Id is "00000000-0000-0000-0000-000000000000"
Solution 1:[1]
Spring Data uses the same object reference to apply the update of the ID at. Since you set the ID to a final value Spring Data can't apply a new generated ID to it. The ID will also only be generated if the value is null otherwise the value which is already set will be used.
There is a workaround:
@Table("my_user")
data class MyUser(
@Id
@Column("id")
private var _id: UUID? = null,
val name: String = "blubb"
) {
val id: UUID
get() = _id ?: UUID(0, 0)
}
But it is basically bad practice as answered here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | StefanD |
