DDD | JPA — вопрос дизайна, который может повлечь за собой пожертвование дизайном ради эффективности

#java #jpa #jakarta-ee #domain-driven-design #ddd-repositories

#java #jpa #джакарта-ee #дизайн, управляемый доменом #ddd-репозитории

Вопрос:

Я довольно новичок в DDD, но мне нравится, как дизайн обеспечивает соблюдение структуры в вашем коде (при условии, что вы придерживаетесь принципов). У меня есть головоломка, в которой, как я полагаю, для решения проблемы мне нужно пожертвовать дизайном, чего я не хочу делать. Но прежде всего, я хочу отметить, что я, возможно, изначально неправильно проектировал это из-за своего невежества.

У меня есть приложение, в котором есть объект, содержащий большой двоичный объект в терминологии базы данных. Давайте назовем эту сущность child . child поэтому имеет большой размер из-за того, что содержит большой двоичный объект. Теперь, child можно найти по идентификатору AR, давайте назовем AR parent . Существует также другой уровень выше, ( grandparent ), но этот уровень не нужен, поскольку child содержит желаемые данные для передачи пользователю и parent может быть найден по запросу пользователя (однако для получения родительского элемента на стороне приложения требуется некоторый сложный поиск).

Теперь parent содержит многие из child (отношение «один ко многим»), но мне нужно только одно child для каждой транзакции, поэтому запрашивать весь результат parent и child для каждого запроса определенно не требуется. Выполнение этого запроса для каждой транзакции также было бы невероятно неэффективным, поскольку я запрашиваю множество дополнительных данных из базы данных, которые я даже не использую в каждой транзакции. Было бы экспоненциально эффективнее, например, сохранять parent локально и выполнять запрос для одного child .

У меня также жесткий SLA, поэтому извлечение child должно быть невероятно быстрым. Мой текущий подход методом перебора заключается в запросе parent , получении только одного из child и предоставлении результата пользователю. Я ищу подход, при котором я мог бы иметь parent локально, без списка child , затем, когда приходит запрос, я запрашиваю один child . Это было бы невероятно быстро и эффективно, поскольку я извлекаю только то, что мне нужно. Но это нарушило бы правила DDD, хотя, поскольку child технически на него ссылается только идентификатор parent и он не был бы его собственным AR.

Комментарии:

1. Вы могли бы попробовать отложить загрузку большого двоичного объекта, сохранив коллекцию дочерних объектов. Однако, какие правила вынуждают вас создавать коллекцию дочерних элементов в parent ? Почему child это не может быть собственный агрегат? Также помните, что ваша объектная модель предназначена для обработки команд, а не запросов. Если вы извлекаете данные только для отображения, забудьте о своих объектах и перейдите непосредственно к БД.

Ответ №1:

Я бы выполнил эти шаги:

  1. Измените ParentRepository , чтобы загрузить родительский элемент с его дочерними элементами и без их BLOB столбца. например @Query("select c.id, c.name from Child c where c.parentId = ?1")
  2. Ленивая загрузка BLOB столбца всякий раз, когда это необходимо.

Примечание: в зависимости от ситуации вы можете захотеть использовать кэш для отложенной загрузки. например, библиотека Guava.

Комментарии:

1. Я думаю, что вы имели в виду BLOB не BLOG во втором пуле.