1. 简介

在使用 ORM(对象关系映射)框架将 Java 对象持久化到数据库时,我们常常会遇到一些不需要存储到数据库中的字段。如果该框架遵循 JPA 规范,我们可以通过添加 @Transient 注解来标记这些字段,使其不参与持久化操作。

本篇文章将演示如何正确使用 @Transient 注解,并探讨它与 Java 原生 transient 关键字之间的区别与联系。

2. @Transient 注解 vs transient 关键字

很多开发者对 @Transient 注解和 Java 的 transient 关键字存在混淆:

  • transient 是 Java 原生关键字,主要用于对象序列化过程中忽略某些字段。
  • ⚠️ 但在使用 JPA 框架进行持久化时,transient 同样会使字段不被保存到数据库中。
  • ❌ 相反,@Transient 只作用于 JPA 持久化过程,不会影响 Java 对象的序列化行为

简单总结:

特性 @Transient transient
作用范围 仅限 JPA 持久化 序列化 + JPA 持久化
是否参与序列化 ✅ 参与 ❌ 不参与

3. JPA 中使用 @Transient 示例

假设我们有一个 User 类,它是一个 JPA 实体,映射到数据库中的 Users 表。当用户登录后,我们会从数据库加载用户记录,然后在内存中给该实体设置一些额外字段,这些字段并不对应数据库中的列。

比如我们要记录用户本次登录的时间戳:

@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 对象时,由于 loginTime 字段被标记为 @Transient,因此不会被写入数据库。

但如果我们将该对象进行序列化并传递给其他服务,loginTime 字段仍会被包含在序列化结果中。

如果我们希望该字段在序列化时也被忽略,则应使用 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. 小结

本文介绍了 @Transient 注解的典型使用场景,并对比了其与 Java 原生 transient 关键字的区别。如果你正在使用 JPA,合理使用 @Transient 能让你更灵活地控制实体类中哪些字段需要持久化。

📌 更多 JPA 相关内容可以查看:JPA 分类文章

📘 完整源码请见 GitHub:https://github.com/eugenp/tutorials/tree/master/persistence-modules/java-jpa-3


原始标题:Ignoring Fields With the JPA @Transient Annotation | Baeldung