Создать сущность внутри сущности: как сохранить - PullRequest
2 голосов
/ 08 декабря 2011

При использовании Object Relational Mapper, как я могу создавать новые сущности внутри другой сущности и как я могу их сохранить? Я использую Doctrine 2 (PHP), но полагаю, что это одинаково хорошо применимо и к Hibernate (Java) и NHibernate (C #).

Например, O имеет сущность Order, которая имеет метод setCompleted(). Моя бизнес-логика гласит, что всякий раз, когда заказ выполнен, создается новая сущность Product. Обратите внимание, что Order и Product в настоящее время не связаны (должны ли они быть?). Для меня самое логичное место, чтобы поместить эту бизнес-логику в метод setCompleted(). Но как мне сказать ORM, что существует новая сущность, которая будет сохраняться? Менеджер сущностей не доступен внутри сущности.

Или я неправильно подхожу к этой проблеме и должен ли я реализовать ее другим способом?

Ответы [ 3 ]

1 голос
/ 08 декабря 2011

Я бы создал новый продукт как часть метода setCompleted.Таким образом, каждый раз, когда Продукт сохраняется, все сопоставленные объекты также сохраняются.Просто позвольте hibernate сделать работу ноги ... не сохраняйте ее явно, используя сервисный уровень.

Например, в Order (при условии, что продукт правильно объявлен как объект):

@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="product_fk",nullable = false) 
private Product product;

public void setCompleted(){
 setProduct(new Product(...));
}

DDD с гибернацией

1 голос
/ 08 декабря 2011

Вы должны создать этот новый продукт из уровня обслуживания. Например. у вас может быть OrderService, который подключает (общается) с вашим хранилищем заказов и хранилищем продуктов. Когда вы вызываете SetCompleted (), вы также создаете продукт (через Репозиторий продуктов).

Вы также можете посмотреть шаблон Pipes and Filters и создать конвейер заказов. Таким образом, вы можете подключать различные шаги (фильтры), которые выполняются один за другим.

Вы не должны создавать продукт из сущности Order, потому что ваши доменные сущности должны быть независимыми от базы данных. Для создания нового продукта вам нужен репозиторий, поэтому уровень обслуживания облегчает это, общаясь с уровнем доступа к данным.

1 голос
/ 08 декабря 2011

В классе заказа необходимо указать ссылку на продукт, который может быть нулевым.Когда вы вызываете setCompleted, вы можете создать новый экземпляр Product и назначить его.Что-то вроде

public void setCompleted(){
 ... 
 this.product = new Product(...);
 ...
}

, тогда в зависимости от вашего сопоставления (обратитесь к документации ORM), вам нужно будет вызвать метод сохранения менеджера entiity как для заказа, так и для продукта, или просто заказать (если владельцем отношения является Закази каскад включен).

Поскольку это бизнес-логика, я бы не скрывал ее в самой модели, а скорее на уровне обслуживания.

...