2011-02-28 103 views
3

我在PGSQL DB上使用JPA/Hibernate。JPA:每當創建另一個實體時創建一個實體

我在我的應用程序中有一個實體,並且我想在每次第一個實體持久化時堅持另一個實體(不同類型)。例如,無論何時創建「ORDER」,我都想立即保留一個空的「ORDER_INVOICE」實體並將其連接到該訂單。這些駐留在兩個不同的表中。

起初我想爲ORDER實體編寫一個@PostPersist函數,並在其中保存ORDER_INVOICE,但是我的問題是我沒有這個上下文中的實體管理器。

我正在尋求避免記住在每個ORDER持久性上堅持ORDER_INVOICE。

這是正確的路嗎?如果是這樣,我如何才能讓EM進入PostPersist?如果不是,那麼更好的方法是什麼?

+0

「創造」你的意思是「堅持」? – MRalwasser 2011-02-28 12:03:04

+0

@MRalwasser:是的。 – 2011-02-28 12:24:49

+0

這樣做似乎沒有標準化的方式:從JPA 1.0規範:'「一般來說,可移植應用程序不應調用EntityManager或查詢操作, 訪問其他實體實例,或修改生命週期回調方法中的關係。 。也許你可以使用@JB Nizet所說的解決方案。 – MRalwasser 2011-02-28 12:53:24

回答

3

爲什麼不簡單地在主實體的構造函數中創建它,並設置cascade =堅持關係?

@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); 
    } 

    // ... 
} 

編輯:

爲了避免每個訂單的構造函數被調用時創建一個新的發票(通過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); 
    } 

    // ... 
} 

如果該訂單在被工廠方法實例化後仍然存在,那麼發票也將持續存在(感謝級聯)。如果訂單沒有保存,那麼它將在某個時間點被垃圾收集,並且它的默認invoide也是。

+0

因爲那麼訂單的每個結構都會自動創建一個新的發票,而我只希望它在持續訂單(只完成一次)上創建。此外,我的情況下的訂單不知道/關心發票(雖然這可以更改)。 – 2011-02-28 12:17:17

+1

你可以讓你的默認構造函數受到保護。從數據庫加載實體時,它仍將由您的JPA引擎調用。並且您會添加一個靜態工廠方法,該方法將創建訂單及其默認發票,如我的答案。 – 2011-02-28 12:24:30

+0

我明白你的意思了。所以讓我重申 - 我會做出一個方法:1)創建一個新訂單2)用所有需要的數據填寫訂單3)堅持訂單4)創建發票5)將發票連接到訂單6)堅持發票。這聽起來不錯。這是你的意思嗎? – 2011-02-28 12:32:41

相關問題