Answers:
Java的transient
关键字用于表示不对字段进行序列化,而JPA的@Transient
注释用于表示不将字段保留在数据库中,即它们的语义不同。
因为它们有不同的含义。该@Transient
注解告诉JPA提供者不能坚持任何(非transient
)属性。另一个告诉序列化框架不要序列化属性。您可能想拥有一个@Transient
属性并仍然对其进行序列化。
正如其他人所说的,@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时,它会持久化gender
和id
并且不会尝试持久化辅助布尔方法-如果没有@Transient
基础系统,则会抱怨Entity类Person
丢失了setMale()
,setFemale()
方法也就不会持久化Person
。
目的不同:
该transient
关键字和@Transient
注释有两个不同的目的:一个交易序列化,并与一个交易的持久性。作为程序员,我们经常将这两个概念合而为一,但这通常并不准确。持久性是指状态的特性超过了创建状态的过程。Java中的序列化是指将对象的状态编码/解码为字节流的过程。
该transient
关键字是比更强的条件@Transient
:
如果某个字段使用transient
关键字,则在将对象转换为字节流时,该字段不会被序列化。此外,由于JPA将标有transient
关键字的字段视为具有@Transient
注释,因此JPA也不会保留该字段。
另一方面,当对象被序列化时,@Transient
单独注释的字段将转换为字节流,但是JPA不会将其保留。因此,transient
关键字是比@Transient
注释更强的条件。
例
这就引出了一个问题:为什么有人要序列化一个未持久化到应用程序数据库的字段?现实情况是,序列化不仅用于持久性。在企业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
。Solution
通过算法定位最终版本后,JPA会直接将其持久化,而无需使用ProgressReport
。
@Unpersisted
。
@Ephemeral
。根据梅里亚姆·韦伯斯特(Merriam Webster)的说法:短暂的东西在1600年代首次以英语印刷时,“它是一个科学术语,用于短期发烧,后来应用于寿命很短的生物(例如昆虫和花朵)。不久之后,它获得了一种泛指,指的是任何短暂而短暂的事物(例如“短暂的快乐”)。”
transient
字段视为隐含@Transient
注释。因此,如果您使用transient
关键字来防止字段的序列化,那么该字段也不会最终出现在数据库中。
如果只希望某个字段不会保留,那么瞬时和@Transient都可以工作。但是问题是为什么@Transient因为瞬态已经存在。
因为@Transient字段仍会序列化!
假设您创建一个实体,进行一些耗时的CPU计算以获得结果,而该结果将不会保存在数据库中。但是,您要将实体发送给其他Java应用程序以供JMS使用,那么您应该使用@Transient
,而不是JavaSE关键字transient
。因此,在其他VM上运行的接收器可以节省时间来重新计算。