338

Javaにはtransientキーワードがあります。なぜ JPA は@Transient既存の java キーワードを単に使用する代わりに持っているのですか?

4

8 に答える 8

534

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

于 2010-01-28T13:03:20.333 に答える
128

意味が違うからです。@Transientアノテーションは、JPA プロバイダーに (非transient) 属性を保持しないように指示します。もう 1 つは、属性をシリアル化しないようにシリアル化フレームワークに指示します。@Transientプロパティを持っていても、それをシリアル化したい場合があります。

于 2010-01-28T13:04:01.310 に答える
118

他の人が言ったように、@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 に供給されると、genderandは永続化idされますが、ヘルパーのブール メソッドを永続化しようとはしません@Transient。基盤となるシステムがなければ、エンティティ クラスとメソッドPersonが見つからないため、まったく永続化されないと文句を言うでしょう。setMale()setFemale()Person

于 2010-01-28T13:29:01.640 に答える
66

目的が異なります:

transientキーワードと@Transient注釈には 2 つの異なる目的があります。1 つはシリアライゼーションを扱い、もう 1 つは永続性を扱います。プログラマーとして、私たちはしばしばこれら 2 つの概念を 1 つに結び付けますが、これは一般的に正確ではありません。永続性とは、状態を作成したプロセスよりも長く存続する状態の特性を指します。Java でのシリアル化とは、オブジェクトの状態をバイト ストリームとしてエンコード/デコードするプロセスを指します。

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

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

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

ここで疑問が生じます: アプリケーションのデータベースに永続化されていないフィールドをシリアル化する必要があるのはなぜでしょうか? 実際には、シリアライゼーションは永続化以上の目的で使用されますEnterprise 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ます。finalSolutionがアルゴリズムによって特定されると、. を使用せずに JPA によって直接永続化されProgressReportます。

于 2016-02-26T01:55:26.033 に答える
21

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

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

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

于 2015-11-18T04:15:45.947 に答える
1

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

于 2015-12-16T19:36:37.560 に答える