2010-08-31 68 views
12

試想一下,一個事件實體引用狀態實體:JPA最佳實踐:靜態查找實體

@Entity 
@Table(name = "event") 
public class Event() 
{ 
    @Id 
    @Column(name = "id", nullable = false) 
    private long id; 
    ... 

    @ManyToOne 
    @JoinColumn(name = "status_code", nullable = false) 
    private Status status; 
} 


@Entity 
@Table(name = "status") 
public class Status() 
{ 
    @Id 
    @Column(name = "code", nullable = false) 
    private String code; 

    @Column(name = "label", nullable = false, updatable = false) 
    private String label; 
} 

狀態被映射到一個小桌子 'status'。 狀態是一個典型的參考數據/查詢實體。

code label 
    ----- -------------- 
    CRD Created 
    ITD Initiated 
    PSD Paused 
    CCD Cancelled 
    ABD Aborted 

我不知道如果是狀態建模爲一個實體是一個好主意。感覺更像是常量的枚舉...

通過映射狀態作爲一個實體,我可以在Java代碼中使用Status對象,並且狀態值在數據庫中同樣存在。這對報告很有用。另一方面,如果我想爲事件設置一個特定的狀態,我不能簡單地指定我想到的常量狀態。我必須先查找合適的實體:

event.setStatus(entityManager.find(Status.class, "CRD")) 

我可以避免上述代碼片段嗎?我怕性能損失,它看起來很重...

  • 我必須調整隻讀屬性的東西嗎?
  • 我可以預取這些查找實體並將它們用作常量嗎?
  • 我錯過了關鍵的JPA功能嗎?
  • ...?

歡迎各位意見/建議/建議!

謝謝! J.

回答

3

我可以避免上述代碼片段嗎?我很害怕表現的懲罰,它看起來很沉重?

那麼,你可以使用enum來代替。我真的不明白你爲什麼不實際。

但是,如果你真的想使用一個實體,那麼它將是二級緩存的完美候選人,這將解決你的性能問題。

+1

我可以將狀態建模爲枚舉。這將允許在事件中清潔和有效地設置狀態值。 「代碼」和「標籤」都可以建模爲屬性。太酷了。但是,我是否正確理解「標籤」信息在數據庫中不可用?這對於外部報告來說有點不幸:我的Java應用程序之外可能需要訪問數據庫的工具。或者我忽略了什麼? Enums可以映射到他們自己的數據庫表嗎? – Jan 2010-09-02 08:33:43

+0

我將不得不仔細看看二級緩存。無意中,您是否知道任何允許輕鬆監控Hibernate中二級緩存的工具? – Jan 2010-09-02 10:47:58

+0

@Jan對,你不會在數據庫中使用枚舉標籤。但我實際上在枚舉中使用'Created','Initiated'等,而不是代碼。無論如何,使用實體對你來說確實可能更好。在這種情況下,@Jörn的建議是一個很好的建議。儘管如此,這個只讀實體仍然是L2緩存的理想選擇。關於監控,它依賴於L2緩存提供商。 – 2010-09-02 12:19:19

9

您可以使用entityManager.getReference(Status.class, "CRD"),如果該實體僅用於設置外鍵,則該實體可能無法從數據庫獲取該實體。

+0

好!這是我正在尋找的那種提示。 – Jan 2010-09-02 08:13:04