本文正在参加「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 时,它会持久化 id
和 gender
两个属性,但不会去尝试持久化两个返回值为 boolean
的属性,如果没有 @Transient
注解,系统底层就会发出警告说 Person
类缺少 setMale
和 setFemale
方法,因此就不会对 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?