как хранить в БД граф value object
Задача: имеется доменная модель состоящая из классов
public class EntityA {
private UUID id;
private String someValue;
private Set<ValueObjectA> valueObjects;
//... остальной код
}
public class ValueObjectA {
private final String someValue;
private final Set<ValueObjectB> valueObjects;
//... остальной код
}
public class ValueObjectB {
private final String someValue;
//... остальной код
}
Как видно из названия классов - объекты типа EntityA являются сущностями(в терминах DDD), а объекты типов ValueObjectA и ValueObjectB - объектами значениями. Нужно определить каким образом хранить в БД данный граф объектов.
Что вызвало у меня трудности: связь между EntityA и ValueObjectA - один-ко-многим, между ValueObjectA и ValueObjectB тоже один-ко-многим. В этом случае логично для каждого класса создать отдельную таблицу в БД и связать эти таблицы между собой. Проблема возникает в связывании этих таблиц. Я не хочу добавлять в классы ValueObjectA и ValueObjectB идентификаторы, хочу чтобы они остались полноценными value object. В этом случае связать таблицы EntityA и ValueObjectA очень просто, а вот как связать таблицы ValueObjectA и ValueObjectB - я ума не приложу.
Ответы (1 шт):
Сначала замечу, что для value object неприменимо понятие мощность cвязи. Мощность связи определена для связи между сущностями. По-этому, некорректно говорить
связь между EntityA и ValueObjectA - один-ко-многим
Вы пишете
не хочу добавлять в классы ValueObjectA и ValueObjectB идентификаторы, хочу чтобы они остались полноценными value object.
Так вам этого и не нужно делать. Для хранения EntityA.valueObjects вам нужна таблица ENTITY_A_VALUE_OBJECT_A, в которой нужен только внешний ключ на ENTITY_A.ID. Репозиторий при загрузке EntityA прочитает ассоциированные записи из ENTITY_A_VALUE_OBJECT_A. Аналогично для ValueObjectB создайте таблицу ENTITY_A_VALUE_OBJECT_A_VALUE_OBJECT_B и там точно так же храните внешний ключ на ENTITY_A. Своего идентификатора ни у ValueObjectA ни у ValueObjectB нет и поле в классе не нужно.
Альтернативный вариант это сериализировать Set<ValueObjectA> одно значение (может быть строка json/xml/свой формат, или просто массив байт) и хранить в поле в таблице ENTITY_A.