8

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: タイプ「class aa.Adkeys」で指定された ID クラス「class aa.AssetType」には、引数なしのパブリック コンストラクターがありません。

だから私の質問は:

  • JPAのエンティティのIDとして列挙型を使用できるようにする必要がありますか? (つまり、OpenJPA にバグがあります)
  • または私はどこかで間違いを犯していますか?
  • そのような問題の回避策はありますか?
4

4 に答える 4

8

JPA 仕様では、これが可能であるとは述べていません。

2.1.4 主キーとエンティティ ID

主キー (または複合主キーのフィールドまたはプロパティ) は、次のいずれかの型である必要があります。任意の Java プリミティブ型。任意のプリミティブ ラッパー タイプ。java.lang.String; java.util.Date; java.sql.Date. ただし、概して、近似数値型 (浮動小数点型など) は主キーには使用しないでください。主キーがこれら以外の型を使用するエンティティは移植できません。

特定のエンティティに対してコンパイル時に固定数のレコードが本当に必要な場合は、Stringまたは主キーを使用して、またはintを割り当てることができます。AssetType.FOO.name()AssetType.FOO.ordinal()

ここでの非移植性とは、一部の永続化プロバイダーが他のものをサポートしている可能性があることを意味しますが、別のプロバイダーでは機能しない可能性があります。列挙型と同様に、永続化プロバイダーがそれを特別にサポートしている場合、それはインスタンス化を試みませんが、 if をチェックした後に特別に処理しますclass.isEnum()。しかし、永続化プロバイダーはこれを行わないようです。

于 2010-09-15T12:53:54.683 に答える
4

いいえ、列挙型を ID として使用することはできません。JPA では ID 列に独自のマッピングを定義することが許可されていないためです ( JPA が で作成できるintまたはまたは である必要があります)。longnew

ID はビジネス キーであってはなりません (あなたの場合: タイプ)。ビジネス キーを ID として使用することは、DB 設計でよくある間違いであり、後であらゆる種類の問題を引き起こすため、避ける必要があります。

問題を解決するには、独立した ID 列を追加します。

于 2010-09-15T12:55:51.603 に答える
2

OpenJPAは、これをサポートしていない唯一のJPAプロバイダーです。主キータイプとしてのサポート列挙型を参照してください

于 2011-05-28T02:09:14.443 に答える
0

本当にこれをしたいですか?この構成では、コード内の列挙型を更新せずにデータベースの列挙型キーを変更することはできません(ロード時に失敗します)。また、その逆もできません(制約の失敗)。int pkとnameを使用してAssetTypeテーブルを作成し、AdkeysにAssetType.idへの外部キーをpkとして持たせてみませんか?

アプリでAssetTypeを列挙する必要がある場合は、起動時にデータベースからAssetTypesを読み込むことができます。

于 2010-09-15T13:08:33.337 に答える