spring-projects / spring-data-r2dbc

Provide support to increase developer productivity in Java when using Reactive Relational Database Connectivity. Uses familiar Spring concepts such as a DatabaseClient for core API usage and lightweight repository style data access.
Apache License 2.0
708 stars 132 forks source link

Save entity with custom UUID identifier #853

Closed detomarco closed 6 months ago

detomarco commented 7 months ago

Hello,

I need to persist an object with UUID generated code side.

@Table("cars")
public class Car {
    @Id
    private UUID id;
    private String name;
    // getters - setters
}

public interface CarRepository extends ReactiveCrudRepository<Car, UUID> {
}

@Test
void contextLoads() {
     Car car = new Car();
     car.setId(UUID.randomUUID());
     car.setName("BMW");

     Mono<Car> saved =  carRepository.save(car);
     saved.block();
}

but I get this error


org.springframework.dao.TransientDataAccessResourceException: Failed to update table [cars]; Row with Id [648e8774-0a5a-49b9-9c93-d435403d0050] does not exist
    at org.springframework.data.r2dbc.core.R2dbcEntityTemplate.lambda$doUpdate$12(R2dbcEntityTemplate.java:640)
    at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:113)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
    at reactor.core.publisher.MonoUsingWhen$MonoUsingWhenSubscriber.deferredComplete(MonoUsingWhen.java:268)

In my understanding, spring-data-r2dbc uses id to check if the entity is already persisted and it fails when id is set but not found in the database. Is this an expected behaviour/limitation of the library? The only way I found to achieve this is to insert the object manually via DatabaseClient, which is inconvenient in my opinion

Here the project to reproduce the issue Spring boot version: 3.2.2

rrrship commented 7 months ago

Try to add @Version property to your entity. I think then it will check based on the version if it's a new entity or not, and it doesn't try to update it.

mp911de commented 6 months ago

Is this an expected behaviour/limitation of the library?

It is indeed as we fall back to the identifier to determine whether to insert or update an entity. Check out the documentation on Entity State Detection Strategies.