JPAに@Transientアノテーションがあるのはなぜですか?


回答:


455

Javaのtransientキーワードは、フィールドがシリアル化されないことを示すために使用されますが、JPAの@Transient注釈は、フィールドがデータベースに永続化されないこと、つまりセマンティクスが異なることを示すために使用されます。


3
はい、セマンティクスは異なります。しかし、なぜJPAはこのように設計されたのでしょうか。
Dilum Ranatunga、2010

1
私はあなたを理解しているのかわかりませんが、 "Pascal Thivent"の答えを見てください;)
Jawher

30
データベースにデータを保存する必要はないかもしれませんが、エンティティの保存/復元にシリアル化を使用するJPA Chachingシステムに保存したいので、これは便利です。
Kdeveloper

1
エンティティの保存/復元にシリアル化を使用する「JPAキャッシュシステム」とは何ですか?JPA実装はオブジェクトを任意の方法でキャッシュでき、シリアライゼーションはそれに関与しません。
DataNucleus、

@Jawher、ここで一時的ではない耐性は、値を事前に設定しないことを意味します。そうしないと、その属性にデフォルト値が挿入されます。
Satish Sharma 2013年

115

意味が違うから。@Transient注釈は、任意の(非永続化しないようにJPAプロバイダを伝えますtransient)属性を。もう1つは、属性をシリアル化しないようにシリアル化フレームワークに指示します。@Transientプロパティが必要な場合でも、それをシリアル化できます。


パスカルの回答ありがとうございます。コメントのメモとして、「@ Transientプロパティを用意し、それをシリアル化することもできます。」(それが私が探していたものです)また、その反対は真実ではないことも付け加えておきます。変数を一時変数として設定すると、永続化できなくなります。
jfajunior

96

他の人が言ったように、@Transient永続化すべきではないフィールドをマークするために使用されます。この短い例を考えてみましょう:

public enum Gender { MALE, FEMALE, UNKNOWN }

@Entity
public Person {
    private Gender g;
    private long id;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public long getId() { return id; }
    public void setId(long id) { this.id = id; }

    public Gender getGender() { return g; }    
    public void setGender(Gender g) { this.g = g; }

    @Transient
    public boolean isMale() {
        return Gender.MALE.equals(g);
    }

    @Transient
    public boolean isFemale() {
        return Gender.FEMALE.equals(g);
    }
}

このクラスはJPAに供給されると、それが持続genderしてidますが、ヘルパーのboolean型メソッドを保持しようとしない-ことなく、@Transient基本となるシステムエンティティ・クラスがと文句を言うだろうPerson不足しているsetMale()setFemale()メソッドひいては持続しないだろうPerson、すべてで。


@pspでは、なぜ/どのようにして不特定の動作が発生する可能性があるかについて詳しく説明できますか?ありがとう!
taiduckman、2015

@ 40Plot仕様はそう述べています
psp

7
これは、現在受け入れられているものをはるかに説明しているため、私見の受け入れられた答えである必要があります...
Honza Zidek

53

目的が異なります:

transientキーワードと@Transientと1件の情報:注釈は、二つの異なる目的で持ってシリアライズとで1つの取引永続性を。プログラマーとして、これら2つの概念を1つに統合することがよくありますが、これは一般的に正確ではありません。永続性は、それを作成したプロセスよりも長く存続する状態の特性を指します。シリアライゼーション Javaでは、バイトストリームとしてオブジェクトの状態を符号化/復号化のプロセスを指します。

transientキーワードは、より強い条件であります@Transient

transientフィールドがキーワードを使用する場合、オブジェクトがバイトストリームに変換されるときにそのフィールドはシリアル化されません。さらに、JPAはtransientキーワードでマークされ@Transientたフィールドを注釈を持つものとして扱うため、フィールドもJPAによって永続化されません。

一方、注釈付きフィールド@Transientのみがしますオブジェクトがシリアライズされたバイトストリームに変換され、それはJPAによって永続化されることはありません。したがって、transientキーワードは@Transient注釈よりも強い条件です。

これは疑問を投げかけます:なぜ誰かがアプリケーションのデータベースに永続化されていないフィールドをシリアル化したいのですか?現実には、シリアライゼーションは永続化以上の目的で使用されます。エンタープライズJavaアプリケーションでは、分散コンポーネント間でオブジェクトを交換するメカニズムが必要です。シリアライゼーションは、これを処理するための共通の通信プロトコルを提供します。したがって、フィールドは、コンポーネント間通信の目的で重要な情報を保持できます。しかし、同じフィールドは永続性の観点からは価値がない場合があります。

たとえば、最適化アルゴリズムがサーバーで実行されていて、このアルゴリズムの完了に数時間かかるとします。クライアントにとって、最新のソリューションセットを用意することが重要です。したがって、クライアントはサーバーにサブスクライブして、アルゴリズムの実行フェーズ中に定期的な更新を受信できます。これらの更新は、ProgressReportオブジェクトを使用して提供されます。

@Entity
public class ProgressReport implements Serializable{

    private static final long serialVersionUID = 1L;

    @Transient
    long estimatedMinutesRemaining;
    String statusMessage;
    Solution currentBestSolution;

}

Solutionクラスは次のようになります。

@Entity
public class Solution implements Serializable{

    private static final long serialVersionUID = 1L;

    double[][] dataArray;
    Properties properties;
}

サーバーはそれぞれのProgressReportデータベースを維持します。サーバーは永続化を気にしませんestimatedMinutesRemainingが、クライアントは確かにこの情報を気にします。したがって、estimatedMinutesRemainingはを使用して注釈が付けられ@Transientます。ファイナルSolutionがアルゴリズムによって特定されると、それを使用せずにJPAによって直接永続化されProgressReportます。


1
それらが実際に異なる懸念である場合、きっとニュアンスを捉えた別の言葉が存在します。なぜ用語を過負荷にするのですか?スタータ提案として、@Unpersisted
Dilum Ranatunga 2016

4
個人的に好き@Ephemeralです。Merriam Websterによると、1600年代に短命が最初に英語で印刷されたとき、「これは短期間の発熱、およびその後非常に短い寿命を持つ生物(昆虫や花など)に適用される科学用語でした。その後すぐに、それは、(「はかない快楽」のように)つかの間の、そして短命なものに言及する拡張された感覚を獲得しました。」
オースティンD

1
この回答について私が気に入っているのは、JPAがtransientフィールドに暗黙的に@Transient注釈を付けていると見なしていることについて言及していることです。したがって、transientキーワードを使用してフィールドのシリアル化を防止すると、データベースにも反映されません。
neXus 2018年

17

フィールドが永続化されないようにしたい場合は、transient@Transientの両方が機能します。しかし、問題は、一時的なものがすでに存在するため、@ Transientである理由です

@Transientフィールドは引き続きシリアル化されるためです!

エンティティを作成し、CPUを消費する計算を行って結果を取得するとします。この結果はデー​​タベースに保存されません。ただし、JMSで使用するエンティティを他のJavaアプリケーションに送信する@Transient場合は、JavaSEキーワードではなくを使用する必要がありますtransient。そのため、他のVMで実行されているレシーバーは、時間を節約して再計算することができます。


より明確にするために例を提供できますか?
過酷なカナカラ2017年

jpaが一時的なものとして扱うが、ジャクソンはそうしないという注釈はありますか?
Kalpesh Soni

0

「なぜ」の質問に答えてみます。テーブルに多数の列がある巨大なデータベースがあり、プロジェクト/システムがツールを使用してデータベースからエンティティを生成する状況を想像してみてください。(Hibernateにはそれらなどがあります。)ここで、ビジネスロジックによって、永続化されない特定のフィールドが必要であるとします。エンティティを特定の方法で「構成」する必要があります。Transientキーワードはオブジェクトに対して機能しますが、Java言語内で動作するため、@ Transientは永続化タスクのみに関係するタスクに応答するように設計されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.