Spring Data R2DBC
Table of Contents
TODO
TransientDataAccessResourceException
While doing insert
operations, we assume that for any new row that is being inserted into a table, the id
would be null to successfully save into our database. The id
will be generated for us.
What if we provide an id which does not exist?
If we want to store data as new record with the given id
, we can try as shown here.
e.g.
{
"id": 40,
"description": "IPhone",
"price": 500.95
}
We will see this exception.
org.springframework.dao.TransientDataAccessResourceException: Failed to update table [product]. Row with Id [40] does not exist.
at org.springframework.data.r2dbc.core.R2dbcEntityTemplate.lambda$update$5(R2dbcEntityTemplate.java:402) ~[spring-data-r2dbc-1.1.0.RC1.jar:1.1.0.RC1]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ Handler com.vinsguru.reactive.r2dbc.controller.ProductController#upsertProduct(Product) [DispatcherHandler]
|_ checkpoint ⇢ HTTP POST "/product/save" [ExceptionHandlingWebHandler]
This is because we are trying to save a new product. The id field should be null. If it is present, Spring expects the given id to be present in the DB. So we can not insert a new record with the given id. But We can fix this by implementing the Persistable interface. If the isNew method returns new, R2DBC inserts the record with the given id.
@Data
@ToString
public class Product implements Persistable<Integer> {
@Id
private Integer id;
private String description;
private Double price;
@Transient
private boolean newProduct;
@Override
@Transient
public boolean isNew() {
return this.newProduct || id == null;
}
public Product setAsNew(){
this.newProduct = true;
return this;
}
}