2010-09-15 52 views
5

使用JPA,我們可以將枚舉定義爲實體的ID嗎?使用枚舉作爲編號

我已經試過如下:

public enum AssetType { 
    .... 
} 

@Entity 
@IdClass(AssetType.class) 
public class Adkeys { 

    private AssetType type; 

    @Id 
    @Enumerated(EnumType.STRING) 
    @Column(nullable = false) 
    public AssetType getType() { 
     return type; 
    } 

} 

使用OpenJPA中,它抱怨:

org.apache.openjpa.persistence.ArgumentException:該ID級別 「類aa.AssetType」 規定按類型「class aa.Adkeys」沒有公共的無參數構造函數。

所以我的問題是:

  • 我們應該能夠使用枚舉的身份證上的JPA實體? (即在OpenJPA中存在一個錯誤)
  • 或者我在某個地方犯了什麼錯誤?
  • 有沒有解決這個問題的辦法?
+0

@Nathan:那麼它必須是一個錯誤。 – 2010-09-15 12:54:32

回答

7

JPA規範並沒有說這是可能的:

2.1.4主鍵和實體標識

主鍵(或字段或屬性的複合主鍵)應可以是以下類型之一:任何Java基本類型;任何原始包裝類型; java.lang.String中; java.util.Date; java.sql.Date。但是,通常情況下,絕對不應該在主鍵中使用近似數值類型(例如浮點類型)。主鍵使用其他類型的實體將不可移植。

如果你真的想擁有固定的記錄數爲給定的實體編譯時,您可以使用Stringint主鍵,將其指定AssetType.FOO.name()AssetType.FOO.ordinal()

和非便攜式在這裏的意思某些持久性提供者可能支持其他事物,但它可能不適用於其他提供者。與枚舉一樣 - 如果持久性提供者對它有特殊的支持,那麼它不會嘗試實例化它,而是在檢查是否class.isEnum()之後專門處理它,那麼它可能會起作用。但似乎你的持久性提供者不這樣做。

+0

這並不是說這是可能的,但並不是說這是不可能的。它只是說:'主鍵使用非這些類型的實體將不可移植'。事實上,它並不是說一個類可以用作主鍵,但它是可能的。 – nanda 2010-09-15 13:07:47

+0

這是另一回事 - 一個可嵌入的ID。請參閱我的可移植性部分的更新。 – Bozho 2010-09-15 13:27:41

+0

所以我想這是一個有效的增強請求,你不覺得嗎? – nanda 2010-09-15 13:36:58

4

不,您不能使用枚舉作爲ID,因爲JPA不允許定義您自己的ID列映射(它們必須是intlong或JPA可以使用new創建的東西)。

ID不能是商業密鑰(在你的情況下:類型)。將商業密鑰用作ID是數據庫設計中常見的錯誤,應該避免,因爲它會在以後引發各種問題。

添加一個獨立的ID列來解決問題。

+0

我正在使用舊的數據庫。這可能不是很好的設計,但它在那裏。枚舉只是一堆僵化的價值。 – nanda 2010-09-15 13:12:43

0

你真的想這樣做嗎?此構造不允許更改數據庫枚舉鍵,而不更新代碼中的枚舉(加載失敗),也不允許更改(約束失敗)。爲什麼不只是用int pk和name創建一個AssetType表,並且讓Adkeys有一個AssetType.id的外鍵作爲pk?

如果您需要在應用程序中枚舉它們,可以在啓動時從數據庫中加載AssetTypes。

+0

我正在使用舊的數據庫。當然,我可以改變它,但它可能有問題。枚舉只是一堆僵化的價值。 – nanda 2010-09-15 13:11:56