为什么JPA有一个@Transient注解?

Java有transient关键字。 为什么JPA有@Transient而不是简单地使用已经存在的java关键字?

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时,它坚持genderid但不试图持久化帮助器布尔方法 – 没有@Transient基础系统会抱怨实体类Person缺lesssetMale()setFemale()方法从而不会坚持Person

目的不同:

transient关键字和@Transient注释有两个不同的用途:一个用于处理序列化 ,另一个用于处理持久性 。 作为程序员,我们经常把这两个概念结合成一个,但是这通常是不准确的。 持久性指的是超越创造它的过程的国家的特征。 Java中的序列化是指将对象的状态编码/解码为字节stream的过程。

transient关键字比@Transient条件更强:

如果一个字段使用transient关键字,那么当对象转换为字节stream时,该字段不会被序列化。 此外,由于JPA将使用transient关键字标记的字段视为具有@Transient注解,所以该字段也不会被JPA持久化。

另一方面,单独注释@Transient字段在对象序列化时转换为字节stream,但不会被JPA持久化。 因此, transient关键字比@Transient注解的条件更强。

这引出了一个问题:为什么会有人想要序列化一个没有保存到应用程序数据库的字段呢? 现实情况是, 序列化不仅仅用于持久化 。 在企业级Java应用程序中,需要有一种在分布式组件之间交换对象的机制 ; 序列化提供了一个通用的通信协议来处理这个。 因此,为了组件间通信的目的,一个字段可以保存关键信息; 但从持久性angular度来看,同一领域可能没有价值。

例如,假设一个优化algorithm在服务器上运行,假设这个algorithm需要几个小时才能完成。 对客户来说,拥有最新的解决scheme是非常重要的。 因此,客户端可以订阅服务器,并在algorithm执行阶段接收定期更新。 这些更新使用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注释estimatedMinutesRemaining 。 当algorithmfind最终的Solution ,它直接由JPA持久化,而不使用ProgressReport

如果你只是想要一个字段不会持久, 瞬态@Transient工作。 但问题是为什么@ 瞬间已经存在。

因为@Transient字段仍然会被序列化!

假设你创build一个实体,做一些耗费CPU的计算来得到一个结果,这个结果不会保存在数据库中。 但是您想要将实体发送给其他Java应用程序以供JMS使用,那么您应该使用@Transient ,而不是JavaSE关键字transient 。 所以运行在其他虚拟机上的接收者可以节省时间重新计算。

我会试着回答“为什么”的问题。 想象一下,你有一个巨大的数据库,在表中有很多列,你的项目/系统使用工具来从数据库中生成实体。 (Hibernate有这些,等等…)现在,假设你的业务逻辑你需要一个特定的领域不被坚持。 你必须以特定的方式“configuration”你的实体。 当Transient关键字在一个对象上工作时(因为它在一种Java语言中performance出来),@Transient只能用来回答仅仅涉及持久性任务的任务。