-
Notifications
You must be signed in to change notification settings - Fork 132
Entity with assigned Id is not inserted #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Spring Data isn't using R2DBC Client but is itself a client library. Therefore, this ticket reports a constellation that isn't implemented at all. Spring Data R2DBC logs SQL statements to Can you provide a complete, minimal, verifiable sample that reproduces the problem rather than pasted code? It should be available as a GitHub (or similar) project or attached to this issue as a zip file. |
Here is the project contain all above unit test code : https://github.com/start-java/start-r2dbc/tree/spring-data-r2dbc/issue49.
|
Thanks a lot. This expected behavior. Spring Data inspects the Id field. If the id is If you want to insert entities with an assiged Id, then either use
|
Thank you for the answer. I have a question to add. Also the documentation of the Repository.save(...) states "[...] Use the returned instance for further operations as the save operation might have changed the entity instance completely.". So if no return was given from the database, the entity got changed completly, as it is not present in the database (So changed to "empty") |
Hey, I am using Kotlin and the data classes as entities. There is no builtin default handling, when the id is -1 or 0 as indicator to create a row? Goal:
Workaround:
|
@hfhbd I have the same issue with Kotlin's data classes. |
If you set id to null, it works without the need of the Persistable interface and the id is autogenerated in the database. Example: |
At the time I've written my comment, it wasn't possible. I'm sure there were so many versions released in this period. Maybe one of them solved this issue. |
I just fought with this issue for a few hours. There are many use cases where it is important to insert an existing ID. CQRS is a big one, which should be a perfect use case for a reactive framework. I eventually landed on this: @Table
data class AccountView(
val id: UUID,
val name: String,
) : BaseView<UUID>(id)
abstract class BaseView<ID>(
private val id: ID,
) : Persistable<ID> {
@Transient
private var isNew = false
@Id
override fun getId() = id
@JsonIgnore // isNew() is picked up by Jackson, am I crazy here?
override fun isNew() = isNew
fun markNew() {
isNew = true
}
}
accountRepo.save(Account(...).also { it.markNew() }) This seems pretty ugly compared to: @Table
data class AccountView(
@Id val id: UUID,
val name: String,
)
accountRepo.insert(Account(...)) Would it be possible to expose Another issue is that the framework does not recognize default arguments, so this does not work: @Table
data class AccountView(
@Id private val id: UUID,
val name: String,
@Transient private val isNew: Boolean = false
) : Persistable<UUID> {
override fun getId() = id
@JsonIgnore
override fun isNew() = isNew
} I think this looks pretty clean, if default arguments were supported (which is presumably a good idea anyways). Still, having the direct methods would be the cleanest since |
If adding a @Version field(new record is null or 0), it can resolve this issue? |
Experimented a bit on @jnfeinstein's solution to add an // BaseEntity.kt
abstract class BaseEntity<ID>(
private val id: ID,
) : Persistable<ID> {
@Transient
private var isNew = false
@Id
override fun getId() = id
@JsonIgnore
override fun isNew() = isNew
fun markAsNew() {
isNew = true
}
}
fun <T: BaseEntity<ID>, ID> ReactiveCrudRepository<T, ID>.insert(entity: T): Mono<T> =
save(entity.apply { markAsNew() }) // User.kt
@Table("users")
data class User(
@Id val id: UUID,
val email: String,
@Column("first_name")
val firstName: String,
@Column("last_name")
val lastName: String,
) : BaseEntity<UUID>(id) // Usage
import your.package.name.entities.insert
userRepository.insert(User(
id = it.id,
email = it.email,
firstName = it.firstName,
lastName = it.lastName,
)) |
I log out
io.r2dbc.h2.client.SessionClient
as debug, request aupdate
sql notinsert into
sql. Entity not saved andrepository.findById
found nothing.···
2019-01-11 11:37:00.404 DEBUG io.r2dbc.h2.client.SessionClient : Request: UPDATE people SET name = $2 WHERE id = $1 {1: '1d7d50d3-b1a3-4c27-8552-00d2bf9c5b08', 2: 'simter'}
···
The text was updated successfully, but these errors were encountered: