web-dev-qa-db-ja.com

JPAエンティティがSerializableインターフェイスを実装するタイミングと理由は何ですか?

質問はタイトルにあります。以下に、私の考えと調査結果のいくつかを説明しました。

非常に単純なドメインモデル(リレーションシップのない3つのテーブル)がある場合、すべてのエンティティはSerializableを実装しませんでした。

しかし、ドメインモデルがより複雑になると、RuntimeExceptionが発生しました。これは、エンティティの1つがSerializableを実装していないと言いました。

Jiber実装としてHibernateを使用します。

私は疑問に思う:

  1. ベンダー固有の要件/動作ですか?
  2. シリアル化可能なエンティティはどうなりますか?保存または転送のためにシリアル化できる必要がありますか?
  3. どの時点でエンティティをシリアル化できるようにする必要がありますか?
125
Roman

これは通常、HQLとネイティブSQLクエリを混在させる場合に発生します。 HQLでは、Hibernateは渡された型をDBが理解できるものにマップします。ネイティブSQLを実行するときは、マッピングを自分で行う必要があります。そうしないと、デフォルトのマッピングはパラメータをシリアル化してデータベースに送信します(理解できることを期待して)。

53
Aaron Digulla

JPA仕様によると:

エンティティインスタンスが値によって、分離されたオブジェクトとして(たとえば、リモートインターフェイスを介して)渡される場合、エンティティクラスはSerializableインターフェイスを実装する必要があります。

「JSR 220:Enterprise JavaBeansTM、バージョン3.0 Java Persistence APIバージョン3.0、最終リリース2006年5月2日」

105
Conor

エンティティをワイヤ経由で転送する(他の表現にシリアル化する)必要がある場合は、エンティティをSerializableにする必要があり、httpセッションに格納します(サーブレットセッションによってハードディスクにシリアル化されます) )など.

永続性のために、少なくともHibernateではSerializableは必要ありません。ただし、Serializableにすることをお勧めします。

46
Bozho

JSR-317仕様を参照したConorのいい答えを補完するため。通常、EARプロジェクトは、リモートインターフェイスを介して公開されたEJBを持つEJBモジュールで構成されます。この1つのケースでは、エンティティBeanはリモートEJBに集約され、ネットワーク経由で配線されるように構築されるため、エンティティBeanをシリアル化可能にする必要があります。

CDIを使用しないJEE6戦争プロジェクト:シリアル化できないJPAエンティティに裏打ちされたEJBライトを含めることができます。

CDIを使用したJEE6 warプロジェクト: セッション、アプリケーション、または会話スコープを使用するBeanはシリアル化可能である必要がありますが、リクエストスコープを使用するBeanはシリアル化可能である必要はありません。 したがって、基礎となるJPAエンティティBean -同じセマンティクスに従います。

8
Sym-Sym

hibernate docs によると、@ JoinColumnアノテーションを使用している場合:

referencedColumnNameという名前のパラメーターがもう1つあります。このパラメーターは、結合に使用されるターゲットエンティティの列を宣言します。 referencedColumnNameを非主キー列に使用する場合、関連付けられたクラスはSerializableでなければならないことに注意してください。

7
aman maharjan

あなたの問題は、注釈が付けられていない複雑なタイプ(クラス)のフィールドを持つことに関連していると思います。このような場合、デフォルトの処理では、オブジェクトをシリアル化された形式でデータベースに保存します(おそらく、意図したとおりではありません)。例:

Class CustomerData {
    int getAge();
    void setAge(int age);
}

@Entity
Class Customer {
  CustomerData getCustomerData();
  void setCustomerData(CustomerData data)
}

上記の場合、CustomerDataは、シリアル化された形式でデータベースのバイト配列フ​​ィールドに保存されます。

6
Avner Levy

クラスは、シリアル化する場合はSerializableを実装する必要があります。これはJPAに直接関連しておらず、JPA仕様ではエンティティがシリアル化可能である必要はありません。 Hibernateが本当にこれについて文句を言っているのなら、それはHibernateのバグだと思いますが、直接または間接的にエンティティで何かをしていると思います。

4
jarnbjo

http://www.adam-bien.com/roller/abien/entry/do_jpa_entities_have_to を参照してください。Java.io.Serializableの実装は、IIOPまたはJRMP( RMI)JVMインスタンス間。純粋なWebアプリケーションの場合、ドメインオブジェクトはキャッシュ/最適化の目的でHTTPSessionに保存されることがあります。 httpセッションは、シリアル化(パッシベーション)またはクラスター化できます。どちらの場合も、すべてのコンテンツはシリアル化可能でなければなりません。

3
Arun K

永続性についてだけ説明する場合、Serializableは不要ですが、エンティティをSerializableにすることをお勧めします。

domainを使用する代わりに、プレゼンテーション層に直接公開されているentities/DTOオブジェクトを公開する場合、その場合は、 Serializableを実装します。これらのドメインオブジェクトは、キャッシュ/最適化のためにHTTPSessionに保存できます。 http-sessionはシリアル化またはクラスター化できます。また、JVM- instances間でデータを転送するためにも必要です。

DTOを使用して永続層とサービス層を分離する場合、ドメインオブジェクトをSerializableとしてマークすると生産性が低下し、「encapsulation」に違反します。その後、アンチパターンになります。

複合識別子

主キークラスはシリアル化可能でなければなりません。

POJOモデル

エンティティインスタンスをリモートで分離オブジェクトとして使用する場合、エンティティクラスはSerializableインターフェイスを実装する必要があります。

キャッシュ
さらに、clustered第2レベルcacheを実装する場合、エンティティはserializableでなければなりません。識別子はSerializableである必要があります。これは、identifierが2次キャッシュエントリのキーとして使用される可能性があるためです。

また、エンティティをシリアル化するときは、プライベートアクセス修飾子を使用して明示的なserialVersionUIDを必ず指定してください。 serializableクラスがserialVersionUIDを明示的に宣言しない場合、シリアル化ランタイムは、説明されているように、クラスのさまざまな側面に基づいてそのクラスのデフォルトserialVersionUID値を計算するためJava(TM)Object Serialization Specificationで。デフォルトのserialVersionUID計算は、コンパイラの実装によって異なる可能性のあるクラスの詳細に非常に敏感であるため、逆シリアル化中に予期しないInvalidClassExceptionsが発生する可能性があります。

1
Ankur Singhal

postmanまたはajaxまたはangular jsなどを使用してリモートヒットすると、Jackson fastxmlでStackOverflow例外を使用して繰り返しサイクルが発生する可能性があります。

1
tamil

jPAエンティティがリモートEJB操作によってパラメーターまたは戻り値として使用される場合

0
SAR

これは、間違った型のIDを2番目のパラメーターとしてem.find()などに渡すときにスローされるエラーです(つまり、IDではなくエンティティ自体を渡す)。シリアル化可能なJPAエンティティを実際に宣言する必要があることはまだわかっていません。amanの説明に従ってreferencedColumnNameを使用しているのでなければ、実際には必要ありません。

0
Amalgovinus
  1. どの時点でエンティティをシリアル化できるようにする必要がありますか?

2次キャッシュとしてdiskstoreを使用してehcacheを実装します(つまり、@Cacheableエンティティまたはリポジトリ/サービスメソッドのアノテーションにはSerializableが必要です。そうでない場合、キャッシュはエンティティをディスクキャッシュに書き込むのに失敗します(NotSerializableException)。

0
Michal