2015-09-23 81 views
1

我有一個具有多個double值的實體,每個值在存儲之前都必須乘以某個因子。我想使用(單)JPA轉換器乘以具體因素的屬性,但因此我需要知道我在轉換器功能內轉換哪個屬性。在JPA轉換器中獲取屬性名稱或列名稱

有沒有辦法在轉換器函數中獲取屬性名稱或列名稱或將其傳遞給轉換器?

+0

PS:我也想感謝的替代戰略,以實現所需的行爲不破壞抽象的建議。目前我正在研究AOP,但我不確定這是否是一個好主意。 – Tobson

+1

您可以爲所需的屬性創建自己的註釋,並在持久化之前讀取實體中的元數據。 –

回答

1

我不知道你的實體是怎麼樣的,但也許@Access註釋可能會有所幫助 - 當你需要對數據進行簡單的數據轉換(在這個數據庫中讀取或寫入數據時)如果保存前通過setter發生乘法,但getter給出存儲在db中的確切值)。不便之處在於你需要增加它在每個需要這種轉換二傳手:

@Entity 
@Access(AccessType.FIELD) 
public class Item { 

    private static final long FACTOR = 5; 

    @Id 
    private long id; 

    private String name; 

    @Transient 
    private long amount; 

    // getter and setters for id and name 

    @Access(AccessType.PROPERTY) 
    public long getAmount() { 
     return amount; 
    } 

    public void setAmount(long amount) { 
     this.amount = amount * FACTOR; 
    } 
} 
+0

這比我希望的更麻煩,但我想這是最好的方法。 – Tobson

1

我建議使用,而不是轉換器的實體lifecycle listeners。轉換器是可重用的概念,可將任何Java數據類型映射到JPA類型。他們現在沒有關於你的具體實體或領域。另一方面,只能爲整個實體定義生命週期偵聽器,因此您必須爲每個實體創建偵聽器,並按偵聽器知道要轉換的字段的方式進行設計。

實體監聽器可以在數據加載回實體之前調用,例如在實體的數據被持久(插入),更新或在另一側之前。

您需要至少使用@PrePersist,這會在您的新實體插入數據庫之前觸發您的方法 - 在這種方法中,您有機會乘數或做任何你想做的事。有可能是,當從數據庫中讀取實體時,您還希望將數據庫中的數據轉換爲持續之前的初始形式。那麼你也應該使用@PostLoad來轉換回數據。最後,如果您想要在更新時再次應用轉換,則應該使用@PreUpdate(您可以在同一方法上使用@PrePersist和​​)。

下面是一個例子:

@Entity 
public class Item { 
    @Id 
    private long id; 

    // this value will be multiplied by 10 when stored in DB 
    private long size; 
    // this value will be multiplied by 2 when stored in DB 
    private long amount; 

    @PrePersist 
    @PreUpdate 
    public void convertToDbFormat() { 
    size = size * 10; 
    amount = amount * 2; 
    } 

    @PostLoad 
    public void convertFromDbFormat() { 
    size = size/10; 
    amount = amount/2; 
    } 

} 
+0

Thx爲偉大的解釋! – Tobson