2011-02-28 5 views
3

Я использую JPA/Hibernate над PGSQL DB.JPA: Создание объекта всякий раз, когда создается другой объект

У меня есть сущность в моем приложении, и я хочу сохранить другую сущность (другого типа) каждый раз, когда сохраняется первая сущность. Например, всякий раз, когда создается «ORDER», я хочу немедленно сохранить пустой объект ORDER_INVOICE и подключить его к заказу. Они находятся в двух разных таблицах.

Сначала я подумал о написании функции @PostPersist для объекта ORDER и сохранении в нем ORDER_INVOICE, но моя проблема в том, что в этом контексте у меня нет Менеджера сущностей.

Я стараюсь избегать того, чтобы помнить о сохранении ORDER_INVOICE при каждом сохранении ЗАКАЗА.

Это правильный путь? Если да, то как мне получить EM в PostPersist? А если нет, что было бы лучше?

+0

С «созданными» вы имеете в виду «упорство»? – MRalwasser

+0

@MRalwasser: Да. –

+0

Для этого не существует стандартизированного способа: из спецификации JPA 1.0: «В общем, переносные приложения не должны вызывать операции EntityManager или Query, обращаться к другим экземплярам сущности или изменять отношения в методе обратного вызова жизненного цикла." , Возможно, вы можете использовать такое решение, как @JB Nizet. – MRalwasser

ответ

3

Почему бы вам просто не создать его в конструкторе вашей основной сущности и установить cascade = persist на отношения?

@Entity 
public class Order { 

    @OneToMany(mappedBy = "order", cascade=CascadeType.PERSIST) 
    private List<Invoice> invoices = new ArrayList<Invoice>(); 

    public Order() { 
     Invoice i = new Invoice(); 
     i.setOrder(this); 
     this.invoices.add(i); 
    } 

    // ... 
} 

EDITED:

Чтобы не создавать новый счет каждый раз, когда конструктор орденский вызывается (по JPA, например), вы можете использовать этот вид кода:

@Entity 
public class Order { 

    @OneToMany(mappedBy = "order", cascade=CascadeType.PERSIST) 
    private List<Invoice> invoices = new ArrayList<Invoice>(); 

    /** 
    * Constructor called by JPA when an entity is loaded from DB 
    */ 
    protected Order() { 
    } 

    /** 
    * Factory method; which creates an order and its default invoice 
    */ 
    public static Order createOrder() { 
     Order o = new Order(); 
     Invoice i = new Invoice(); 
     i.setOrder(o); 
     o.invoices.add(i); 
    } 

    // ... 
} 

Если заказ сохраняется после того, как он был основан на фабричном методе, тогда счет будет сохранен также (благодаря каскаду). Если заказ не сохраняется, тогда в определенный момент будет собран мусор, а также его значение по умолчанию.

+0

Потому что тогда каждая конструкция заказа автоматически создаст новый счет, тогда как я хочу, чтобы он создавался только при сохранении порядка (который выполняется только один раз). Кроме того, заказ в моем случае не знает/заботится о счете (хотя это можно изменить). –

+1

Вы можете защитить свой конструктор по умолчанию. Он будет по-прежнему вызываться вашим механизмом JPA при загрузке объектов из базы данных. И вы добавили бы статический заводский метод, который создавал бы заказ и его счет-фактуру по умолчанию, как в моем ответе. –

+0

Я понимаю, что вы имеете в виду. Поэтому позвольте мне повторить: я сделаю метод, который будет: 1) создать новый заказ; 2) заполнить заказ всеми необходимыми данными; 3) сохранить заказ; 4) создать счет-фактуру; 5) подключить счет-фактуру к заказу; 6) сохраняйте счет-фактуру. Это звучит хорошо для меня. Это ты имел в виду? –

Смежные вопросы