
Dmitry
15.09.2018
21:42:05
а подскажите плз по логике работы с ОРМ
вот я вытащил из ОРМ модель доменного объекта, смаппил её на доменный объект.
положил этот доменный объект в список
по прошествии времени я хочу обновить этот объект (поменять какое-то поле)
как это правильно сделать? поменять поле и скормить обратно ОРМ?
а вдруг из-за какой-то ошибки в этом объекте поменялось что-то ещё и это сохранение затрёт что-то в базе


Chupa
15.09.2018
22:14:16
Сущность должна быть валидной. Если это не так, то ошибки могут быть в sql запросе, например, если без проверок добавить объекту уникальное свойство, которое есть уже у какой-нибудь записи. В этом случае ничего не сохранится.
Если ошибка в логике приложения случилась и запрос валидный, то, естественно, в базу запишутся "неправильные" данные. Такие дела нужно тестировать. К первому случаю это также относится.
Сохранение по разному работает. В data mapper нужно вызывать метод, который просто сохранит в базу все накопленные изменения. В active record у модели есть метод save или что-то вроде того. Ну это по опыту с Doctrine и Eloquent говорю, в других может быть немного не так.


Dmitry
15.09.2018
22:20:02
у меня это был вопрос по общей работе с ОРМ (в контексте хибернейта)
есть большой DO с несколькими уровнями вложенности и я хочу перестраховаться, чтобы метод сохранения одного «поддерева» не затрагивал другие. этакая перестраховка от случайных ошибок
нашёл три варианта решения
1. кастомный SQL запрос
2. вытащить из базы, изменить и положить обратно
3. специфический SQL запрос на диалекте ОРМ
но, кажется, правильнее обновить DO и смаппить только нужную часть оного в ORM модели, которые и скормить ORM
вопрос на уровень выше (или даже не на один)

Google

Chupa
15.09.2018
22:22:38
И какие ошибки могут произойти?

Dmitry
15.09.2018
22:49:42
логические.
то, что объект валидно изменится из другого места кода. какая-то другая часть, не относящаясе к локальной задаче. ну, например, я хочу сохранить корзину юзера, а у юзера в это время изменился лог посещений.
в функции сохранения корзины я заодно сохраню и лог. вместо того, чтобы сделать это в правильном месте и в нужной транзакции
и эта другая часть ещё не до конца изменилась и не готова к сохранению. в результате я получу ошибку в транзакции и откат безобразия
в соседнем чатике пояснили за сохранение нужных частей.

Alex
15.09.2018
22:58:17
/stat@combot

Combot
15.09.2018
22:58:17
combot.org/c/-1001071233926

Alex
15.09.2018
22:58:27
/stat@combot

Combot
15.09.2018
22:58:28
combot.org/c/-1001071233926

Sergey
15.09.2018
23:04:18


Dmitry
15.09.2018
23:28:05
спасибо за фомализацию
а допускаются ли вложенные агрегаты?
как у Эванса Кузов и Двигатель — два корня агрегата, а может ли сущестовать Машина, которая является более общим корнем агрегата и в которой лежат ссылки на Двигатель и на Кузов?
или при вычлелении более мелкого агрегата родительский объект перестаёт быть агрегатом и в нём просто лежат ссылки на агрегаты поменьше

Aleh
16.09.2018
05:16:08
Агрегат это граница транзакции, нет вложенностей
Нельзя сохранять одно поддерево, ведь это может быть невалидно без второго поддерева

Dmitry
16.09.2018
08:58:51
а если я сохраняю всё дерево разом?
включая все поддеревья
а что значит
Осуществляйте все об ращения к объектам в границах АГРЕГАТА только через его корневой объект.
?
если, есть аггрегат Car. в нем есть список Wheels, то
можно обращаться через car.getWheels().add(new Wheel()) ¹
или нужно в Car делать фасад car.addWheel(new Wheel()) ² ?

Дмитрий
16.09.2018
09:06:07
Классека ооп
Ни один из этих вариантов не верен, достаточно отдельного независимого метода

Google

Dmitry
16.09.2018
09:10:09
а отдельный независимый метод — он где лежит? в корне агрегата или где-то выше?

Aleh
16.09.2018
09:10:56
Второе больше похоже на правду

Dmitry
16.09.2018
09:17:33
а обычно корни агрегата (и сам агрегат) как-то выделяются при нейминге/структурно?
каким-нибудь суффиксом или отдельной директорией, имя которой совпадает с названием корня

Roman
16.09.2018
09:20:43

Sergey
16.09.2018
10:16:00

Dmitry
16.09.2018
13:33:48
https://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DEV-B331
благодарю
а почему у него столько эвентов?
даже на создание BacklogItem — эвент.
это из-за того что сторадж тормознутый и если синхронно возвращать BacklogItem из BacklogItem,create() — поток будет слишком долго ждать?
(и не очень понял идею с очередью мутаций — это чтобы актуализировать доменный объект после сохранения в сторадж?)

Sergey
16.09.2018
13:34:57
это никакого отношения не имеет к транзакциям
ну тот есть как... это про eventual consistency больше, что бы иметь возможностть связывать различные аргегаты в процессы
следующий этап - event sourcing
ну как этап... возможный способ работы приложения, где стэйт приложения вычисляется из стрима ивентов

Aleh
16.09.2018
13:38:28

Sergey
16.09.2018
13:38:34
ну короч event driven штуки могут быть сложны (особенно по началу и особенно если делать как обычно))
потому лучше поискать инфу про типичные фэйлы и косяки)
но если выйдет сделать нормально на ивентах - то вполне вероятно что без них жить ты уже не захочешь. Ну есть еще вариант что все будет так плохо что тебе еще долго не захочется туда влазить)

Aleh
16.09.2018
13:42:24
Начать можно с выступлений грега янга

Sergey
16.09.2018
13:43:33
только надо сделать пометку что точка зрения Грэга от выступления к выступлению меняется)

Dmitry
16.09.2018
13:43:35
или после этого совсем не захочется жить…
а в чем профит событейного программирования, кроме м… большей отзывчивости из-за «обхода» долгих синхронных методов?

Google

Sergey
16.09.2018
13:44:08
гибкость, это по сути то чем должно было быть ООП - message oriented (а событие это лишь вид сообщений) programming

Aleh
16.09.2018
13:44:27
Даже проиграешь немного, потому что они станут еще медленнее

Sergey
16.09.2018
13:44:52
ну и если с ES совмещать - то возможность крутитть вертетть моделью данных как захочешь (если сделано хорошо)

Bohdan
16.09.2018
13:45:25

Aleh
16.09.2018
13:47:43
https://youtu.be/JHGkaShoyNs

Дмитрий
16.09.2018
13:53:48

Aleh
16.09.2018
13:54:01

Дмитрий
16.09.2018
13:57:46

Aleh
16.09.2018
13:59:28
Но это не точно

Evgeniy
16.09.2018
14:01:09
а как же преждевременная оптимизация, насколько я знаю event driven не для скорости юзают же

Дмитрий
16.09.2018
14:01:14
Не позже, просто в другом порядке, возможно будут вообще убраны при ненадобности
Не для скорости, это просто бонусом идёт

Aleh
16.09.2018
14:06:52
Т.е. в целом позже, чем сразу если бы ее пустили, я это имел ввиду
Ну и да, это все не ради скорости выполнения , но даже этот момент решаем

Дмитрий
16.09.2018
14:13:10

Aleh
16.09.2018
14:13:54

Dmitry
16.09.2018
14:34:57
я чуть запутался.
а как обеспечивается консистентность данных агрегатора и данных в базе?
допустим, в корне агрегата есть метод добавления колеса.
я добавляю колесо в коллекцию, открываю транзакцию и пытаюсь сохранить обновлённый список колес через ORM.
а потом посылаю событие, что колеса (или просто агрегат) обновился.
а что если данные не получилось обновить в транзакции?
удалять добавлённое колесо? и возвращать false из метода добавления?

Google

Aleh
16.09.2018
14:36:35
Агрегат сам не пишет в базу, если на этапе записи будет исключение, то будет исключение и агрегат откатится к предыдущему состоянию
Ну и просто можно посмотреть как в гибернейте
Вот так и будет)

Dmitry
16.09.2018
14:39:38
м… я разделил доменные объекты от моделей, которые использует гибернейт через мапперы.
т.е. мне в таком раскладе нужно как-то сохранять предыдущую версию объекта, чтобы откатиться на неё при фэйле транзакции?

Aleh
16.09.2018
14:40:16

Dmitry
16.09.2018
14:43:17
поздно. уже разделил. следующий раз попробую не разделять.
или с разделениям агрегатор перестаёт работать?
а может сохранять через хибернейт а при успехе сохранения обновлять агрегатор и рэйзить эвент с изменением оного

Aleh
16.09.2018
14:43:32
Зачем не ясно


Dmitry
16.09.2018
15:28:59
Агрегат сам не пишет в базу, если на этапе записи будет исключение, то будет исключение и агрегат откатится к предыдущему состоянию
а как называется этот функционал гибернейта? нагуглить не получается.
если просто сохраняю Entity, достаю из базы, открываю сессию, делаю инвалидным поле (ставлю null где not null), коммичу. в результате эхепшн и объект не откатился на состояние вне сессии, продолжая быть невалидным (что, в целом, логично)
А на SO пишут, что Rolling back in-memory objects is not possible. But the correct data is in database, so you just need to forget about your in-memory data, and get a fresh copy of them from the database

knopkod4v
16.09.2018
16:33:29
по ходу мой вариант! ;0

Sergey
16.09.2018
16:36:21
а как называется этот функционал гибернейта? нагуглить не получается.
если просто сохраняю Entity, достаю из базы, открываю сессию, делаю инвалидным поле (ставлю null где not null), коммичу. в результате эхепшн и объект не откатился на состояние вне сессии, продолжая быть невалидным (что, в целом, логично)
А на SO пишут, что Rolling back in-memory objects is not possible. But the correct data is in database, so you just need to forget about your in-memory data, and get a fresh copy of them from the database
за это в hibernate отвечает unit of work. И нет, отката состояния в памяти конечно же не будет, магии не бывает. Просто дропаешь стэйт агрегата и грузишь из базы чистый если хочешь


Adel
17.09.2018
07:00:34
Есть у кого пример VO в котором несколько полейи валидация одного, зависит от значения другого? А то я не могу придумать. Были мысли про широту-долготу, типа если широта 90, то долгота,например 0 должна быть. но это чушь.
\DateTime хороший пример. там число зависит от месяца. нельзя 31 февраля, но можно 31 марта. Но это такое...

Артур Евгеньевич
17.09.2018
07:18:21
срок за преступление))
максимальный и минимальный зависит от статьи

Aleh
17.09.2018
07:27:52

Adel
17.09.2018
09:09:45

Денис
17.09.2018
09:37:25
Подскажите, может ли объект принадлежать не предметной области, а инфраструктуре? Ну, например, объект "электронное письмо", отправкой которых занимается служба на инфраструктурном слое.
Вроде как и модель, но к предметной области не имеет никакого отношения.

Google

Bohdan
17.09.2018
09:39:12
модель данных != доменная

Aleh
17.09.2018
09:44:18

Денис
17.09.2018
10:48:01

Adel
17.09.2018
10:49:33
А HttpRequest?

Денис
17.09.2018
10:49:50
ясно! спасибо )

Ihor
17.09.2018
11:09:19

Денис
17.09.2018
11:09:46
Я уже разобрался. Спасибо. Я зациклился и не видел очевидное