В новом посте из цикла "#ВопросЭксперту" Михаил Поливаха – эксперт сообщества Spring АйО, ответил на мучающий многих вопрос и рассказал про нюансы Spring Data R2DBC.
–––
Работать с RDBMS в реактивных приложениях бывает сложно, и на то есть реальные причины. Тут совершенно неважно, написаны эти приложения с использованием RXJava или Project Reactor, есть некоторые проблемы на стыке концепций. Но надо понимать, что иногда с этим добром приходится работать, поэтому предлагаю взглянуть на пример ниже (полный код можно увидеть в моем playground репо на GitHub'е):
@Table("orders")
public class Order {
@Id
@EqualsAndHashCode.Include
private Long id;
private String status;
@MappedCollection(keyColumn = "order_id", idColumn = "order_id")
private List<OrderItem> orderItems;
}
@Table("order_item")
public class OrderItem {
@Id
@EqualsAndHashCode.Include
private Long id;
private String name;
private double price;
}
public interface OrderRepository extends ReactiveCrudRepository<Order, Long> { }
// INSERT INTO orders(id, "status") VALUES(1, 'NEW');
// INSERT INTO order_item("name", "order_id") VALUES('Lego', 1);
class OrderRepositoryTest extends AbstractPostgreSQLIntegrationTest {
@Test
void testR2dbcAggregateLoading() {
StepVerifier
.create(orderRepository.findById(1L))
.expectNextMatches(order -> {
System.out.println(order);
return order.getOrderItems().size() == 2 && order.getStatus().equals("NEW");
})
.expectComplete()
.verify();
}
}
А теперь ответьте на вопрос: "Пройдет ли тест успешно?". Я специально сделал пример довольно простым, убрал какие-то доп. компоненты/настройки.
На самом деле проблема в том, что у нас не подгрузилось One-To-Many отношение. Казалось бы, в концепцию DDD оно нормально ложится, и в Spring Data JDBC оно работает нормально. В таком случае вопрос: "Что пошло не так и почему?". Наверное, многим будет интересно узнать, что же случилось?
Ответ я разобью на пункты:
1. Это не баг, поддержки любого рода relation'ов в Spring Data R2DBC сейчас нет.
2. Конкретно в текущем случае, который мы рассматриваем, сделать поддержку relation'ов можно.
3. Почему поддержки relation'ов нет сейчас? TL;DR: потому что отсутствует нормальный способ реализовать поддержку relation'ов в общем случае(!) для Aggregates с учетом парадигмы реактивного программирования.
Хочу заметить, что, в целом, реализовать поддержку relation'ов можно, но будут свои нюансы и вытекающие проблемы. Поскольку эта тема очень большая, детали того, почему же так, что делать, и какие планы работы с этим, я поясню на своем докладе на Joker.