I have to re-implement a few back-end services and one of the main requirement is to make the whole flow reactive. Previously the services used hibernate with PostgreSQL so the mentioned connections were provided by the framework.
Since I have to keep the original DB and just change the service implementation I have to use r2dbc-postgresql. I couldn't find any resource about this topic, but my best guess is to do something similar what I would do with JDBC and introduce some new connection tables between my entities.
Yes, this should work. You could potentialy use R2DBC for all operations and use a library (if available) to connect to the database log (e.g. mysql-binlog-connector-java) in a separate process which will catch database changes and then you persist them in your audit tables.
Spring Data R2dbc can be considered as a light-weight ORM framework.
Currently there are a few drivers ready for production, check the R2dbc drivers page for the complete list. H2 database is frequently used in development environment, add the following dependency when using either embedded or file-based H2 database.
The difference between One-to-many , Many-to-one and Many-to-Many is: One-to-many vs Many-to-one is a matter of perspective. Unidirectional vs Bidirectional will not affect the mapping but will make difference on how you can access your data. In Many-to-one the many side will keep reference of the one side.
I am looking into something similar and have come to the same conclusion (1), since there is no support for relations in R2DBC. To migrate a one-to-many relation I first made the collection containing the "many" entities to @Transient in the "one" entity. Persisting the "one" entity is accomplished using the following steps in a reactive sequence:
In code it looks like this:
public <S extends Drawing> Mono<S> save(final S inDrawing) {
final List<Shape> theDrawingShapes = inDrawing.getShapes();
return Mono.defer(() -> {
return Flux.fromIterable(theDrawingShapes)
.log()
.flatMap(theDrawingShape -> {
/* Save the shapes contained in the drawing. */
if (theDrawingShape instanceof Circle) {
final Circle theUnsavedCircle = (Circle) theDrawingShape;
return mCircleRepository.save(theUnsavedCircle);
} else if (theDrawingShape instanceof Rectangle) {
final Rectangle theUnsavedRectangle = (Rectangle) theDrawingShape;
return mRectangleRepository.save(theUnsavedRectangle);
} else {
LOGGER.warn("Unrecognized entity type: {}",
theDrawingShape.getClass().getName());
return Mono.just(theDrawingShape);
}
})
/* Update the drawing, setting the shapes of the drawing to the saved shapes. */
.collectList()
.map(theSavedShapesList -> {
inDrawing.setShapes(new ArrayList<>(theSavedShapesList));
return inDrawing;
})
/* Save the drawing itself. */
.flatMap(theDrawing -> super.save(theDrawing))
.flatMap(theDrawing -> {
/* Save the relations between the drawing and the shapes of the drawing. */
return Flux.fromIterable(theDrawing.getShapes())
.flatMap(theDrawingShape -> {
final var theDrawingShapeRelation = new DrawingShapesRelation();
theDrawingShapeRelation.setDrawingId(theDrawing.getId());
theDrawingShapeRelation.setShapeId(theDrawingShape.getId());
theDrawingShapeRelation.setShapeType(theDrawingShape.getClass()
.getName());
return mDrawingShapesRelationRepository.save(theDrawingShapeRelation);
})
.collectList()
.map(theDrawingShapesRelationList -> theDrawing);
});
});
}
My conclusion this far is that unless you are certain that there are major gains to be made from switching to R2DBC, I would settle for using Spring Data JPA and executing calls to repositories in a separate thread using subscribeOn.
Good luck and happy coding!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With