1. 序章

オブジェクトリレーショナルマッピング(ORM)フレームワークを使用してJavaオブジェクトをデータベースレコードに永続化する場合、特定のフィールドを無視したいことがよくあります。 フレームワークがJavaPersistenceAPI(JPA)に準拠している場合、これらのフィールドに@Transientアノテーションを追加できます。

このチュートリアルでは、@Transientアノテーションの適切な使用法を示します。 また、Javaの組み込みの一時的なキーワードとの関係についても見ていきます。

2. @Transientアノテーションと transientキーワード

一般に、@TransientアノテーションとJavaの組み込みtransientキーワードの関係については多少の混乱があります。 transient キーワードは、主に Javaオブジェクトのシリアル化中にフィールドを無視することを目的としていますが、JPAフレームワークを使用するときにこれらのフィールドが永続化されるのを防ぎます。

つまり、transient キーワードは、データベースに保存するときに@Transientアノテーションと同じ効果があります。 ただし、@TransientアノテーションはJavaオブジェクトのシリアル化には影響しません。

3. JPA @Transientの例

User クラスがあるとします。これは、データベースのUsersテーブルにマップされるJPAエンティティです。 ユーザーがログインすると、Usersテーブルからレコードを取得し、その後、Userエンティティにいくつかの追加フィールドを設定します。 これらの追加フィールドは、これらの値を保存したくないため、Usersテーブルのどの列にも対応していません。

たとえば、 User エンティティにタイムスタンプを設定します。これは、ユーザーが現在のセッションにログインしたときを表します。

@Entity
@Table(name = "Users")
public class User {

    @Id
    private Integer id;
 
    private String email;
 
    private String password;
 
    @Transient
    private Date loginTime;
    
    // getters and setters
}

HibernateなどのJPAプロバイダーを使用してこのUserオブジェクトをデータベースに保存すると、 @Transient アノテーションが原因で、プロバイダーはloginTimeフィールドを無視します。

このUserオブジェクトをシリアル化し、システム内の別のサービスに渡すと、loginTimeフィールドがシリアル化に含まれます。 このフィールドを含めたくない場合は、代わりに@Transientアノテーションをtransientキーワードに置き換えることができます。

@Entity
@Table(name = "Users")
public class User implements Serializable {

    @Id
    private Integer id;
 
    private String email;
 
    private String password;
 
    private transient Date loginTime;

    //getters and setters
}

現在、 loginTime フィールドは、データベースの永続化およびオブジェクトのシリアル化中に無視されます。

4. 結論

この記事では、一般的なユースケースでJPA @Transientアノテーションを適切に使用する方法を調査しました。 永続性の詳細については、必ずJPAの他の記事を確認してください。

いつものように、記事の完全なソースコードは、GitHubから入手できます。