为什么 JPA 中还要有 @Transient 注解 | Java Debug 笔记

本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看 活动链接

问题

既然 Java 中已经有了关键词 transient,那为什么 JPA 中还要有 @Transient 注解,我们为什么不直接用已经存在的关键词呢?

回答

回答 1

Java 中的关键字 transient 是用来表示一个字段不会被序列化,而 JPA 中的 @Transient 注解则是用来表示一个字段不会被持久化到数据库中,两者从根本功能上来讲是完全不同的。

回答 2

因为它俩的含义不一样!@Transient 注解用于告知 JPA 的提供者不要持久化任何属性,而 transient 则用于告知序列框架不要序列化属性。而当我们使用 @Transient 注解后任然可以使用关键字 transient 来对它进行序列化。

回答 3

正如之前的回答所说,@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 时,它会持久化 idgender 两个属性,但不会去尝试持久化两个返回值为 boolean 的属性,如果没有 @Transient 注解,系统底层就会发出警告说 Person 类缺少 setMalesetFemale 方法,因此就不会对 Person 进行持久化。

回答 4

两者功能不同

@Transient 主要用于处理持久化,而 transient 主要用于处理序列化。作为程序员,我们经常把这两个概念混合在一起,但是这是不准确的。持久化指的是状态的特征,他比创造状态的过程要更加持久。而序列化则是指将对象的状态编码/解码为字节流的过程。

而且 transient@Transient 更强大的一点在于:

如果字段使用了 transient 关键字,那么当对象转换为字节流时,该字段将不会被序列化。另外,JPA 会将由 transient 关键字所修饰的字段看做拥有与 @Transient 注解同样的功能,因此此时该字段也不会被 JPA 持久化。

另一方面,当对象被序列化是,带注解 @Transient 的子弹将会被转换为字节流,但它不会被 JPA 所持久化。因此 transient 关键字比 @Transient 注解拥有的功能更强大!

假设有一个程序运行在服务器上,而且该程序需要几小时才能完成运行。对于我们用于来讲,拥有最新的解决方案是十分重要的。因此,客户端可以定于服务器,并在程序执行期间定期接受更新,而这些更新都是使用 ProgressReport 对象提供的:

@Entity
public class ProgressReport implements Serializable{

    private static final long serialVersionUID = 1L;

    @Transient
    long estimatedMinutesRemaining;
    String statusMessage;
    Solution currentBestSolution;

}
复制代码

解决方案可能如下:

@Entity
public class Solution implements Serializable{

    private static final long serialVersionUID = 1L;

    double[][] dataArray;
    Properties properties;
}
复制代码

服务器将每个 ProgressReport 持久化到数据库中。服务器不必关心持久化所需的时间,但客户端必须考虑这些。因此,当时用 @Transient 注解 estimatedMinutesRemaining 对象时,它将直接由 JPA 持久化,而不会使用 ProgressReport

出处

文章翻译自 Stack Overflow:Why does JPA have a @Transient annotation?

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享