Hibernate/JPA 是不是考虑了瞬态修饰符(而不是注释)

Posted

技术标签:

【中文标题】Hibernate/JPA 是不是考虑了瞬态修饰符(而不是注释)【英文标题】:Is Hibernate / JPA taking in consideration the transient modifier ( not the annotation )Hibernate/JPA 是否考虑了瞬态修饰符(而不是注释) 【发布时间】:2011-04-27 22:46:40 【问题描述】:

我想避免序列化(在 JMS / AMF 中),但仍然使用 JPA/Hibernate 保留该字段。

transient 修饰符是我的朋友吗? @Transient 注释和 transient 修饰符是否相关?

java 规范明确指出系统服务不会将瞬态字段保存到持久存储中。但是休眠是系统服务吗? (我不这么认为) http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#78119

java.io.Serialisable 接缝表示调用out.writeObject and in.readObject 进行序列化 http://download.oracle.com/javase/1.4.2/docs/api/java/io/Serializable.html

有什么见解吗?

也许我应该只写一个快速测试,但我会对一个规范更有信心。

谢谢!

【问题讨论】:

【参考方案1】:

transient 修饰符是我的朋友吗? @Transient 注释和 transient 修饰符是否相关?

它们真正不相关,但我担心它们无论如何都不会成为你的朋友,transient 属性不会被 Hibernate/JPA 保留。 JPA 规范是这样写的:

2.1.1 持久字段和属性

实体的持久状态是 由持久性提供程序访问 通过 JavaBeans 样式运行时 属性访问器或通过实例 变量。单一访问类型(字段 或财产访问)适用于 实体层次结构。当注释是 使用,映射的位置 持久化的注释 的字段或持久属性 实体类指定访问类型 作为字段 - 或属性 - 分别基于访问。

如果实体具有基于字段的访问权限,则持久性提供程序 运行时访问实例变量 直接地。 所有非transient 非实例变量 用Transient注释 注释是持久的。什么时候 使用基于字段的访问, 对象/关系映射注释 为实体类注解 实例变量。 如果实体具有基于属性的访问权限,则持久性提供程序 运行时通过访问持久状态 属性访问器方法。全部 没有注释的属性 Transient 注释是持久的。 属性访问器方法必须是 公开的或受保护的。什么时候 使用基于属性的访问, 对象/关系映射注释 为实体类注解 getter 属性访问器。 映射注释不能应用于 是transientTransient。 如果将映射注释应用于 持久字段和属性 或者如果 XML 描述符指定使用 内的不同访问类型 类层次结构。

...

参考文献

JPA 1.0 规范 第 2.1.1 节持久字段 Hibernate 核心参考指南 2.2.2. Mapping simple properties

相关问题

Why does JPA have a @Transient annotation?

【讨论】:

【参考方案2】:

尝试提供writeObject(ObjectOutputStream oos) 实现,它不会调用oos.defaultWriteObject(),而是手动写入所有必要的属性。

但我不确定这是否可行,谷歌是否有必要先致电defaultWriteObject

【讨论】:

这是一个可行的解决方案。但如果可以的话,我想避免它:)【参考方案3】:

Pascal Thivent 发布的 JPA 规范部分看起来相当混乱。实际上,Hibernate 在使用字段访问时尊重transient,但在属性访问的情况下会忽略。也许这是 Hibernate 特有的行为。

例如,在这种情况下bar 没有序列化,但仍然持久化到数据库中:

@Entity
@Access(AccessType.FIELD) // Default access type - field
public class Foo 
    @Id @GeneratedValue
    private Long id;

    transient private String bar;
    ...
    @Access(AccessType.PROPERTY) // Override default access type for this property
    public String getBar()  return bar; 

编辑:由于不清楚这种行为如何符合 JPA 规范,也许更好的选择是为 transient 字段和相应的属性使用不同的名称。

【讨论】:

有趣...而且令人惊讶的是,2.2.2. Mapping simple properties 部分非常明确。显然,这会导致分离实体的合并出现问题,但这很有趣。

以上是关于Hibernate/JPA 是不是考虑了瞬态修饰符(而不是注释)的主要内容,如果未能解决你的问题,请参考以下文章

@Transient 注解和瞬态修饰符有啥区别

什么时候在java中使用瞬态修饰符? [复制]

为啥杰克逊还要序列化瞬态成员?

Hibernate/JPA 中的类型安全主键

Spring Data 和 Redis - 序列化瞬态字段

Spring Hibernate JPA 联表查询