AccessType.FIELD、AccessType.PROPERTY 和 @Access 的用途是啥

Posted

技术标签:

【中文标题】AccessType.FIELD、AccessType.PROPERTY 和 @Access 的用途是啥【英文标题】:What is the purpose of AccessType.FIELD, AccessType.PROPERTY and @AccessAccessType.FIELD、AccessType.PROPERTY 和 @Access 的用途是什么 【发布时间】:2012-12-02 05:01:41 【问题描述】:

我只是想知道所有这些注释之间的区别。我们为什么要使用这些...意味着它们没有效果,尤其是字段级别和属性级别。

以及使用混合级别注释的目的是什么:

@Entity
@Access(AccessType.FIELD)
class Employee 
    // why their is a field level access 
    private int id;

    // whats the purpose of transient here
    @Transient                               
    private String phnnumber;

    // why its a property level access
    @Access(AccessType.property)             
    public String getPhnnumber() 
        return "1234556";
    


这门课到底说了什么?

【问题讨论】:

另见优秀比较讨论:***.com/questions/594597/… 【参考方案1】:

默认情况下,访问类型由您放置标识符注释的位置定义 (@Id)。如果你把它放在场上 - 它将是AccessType.FIELD,如果你把它放在吸气剂上 - 它将是AccessType.PROPERTY

有时您可能想要注释的不是字段而是属性(例如,因为您希望在 getter 中有一些任意逻辑,或者因为您更喜欢这种方式。)在这种情况下,您必须定义一个 getter 并将其注释为 AccessType.PROPERTY .

据我所知,如果您在任何实体字段/方法上指定AccessType.FIELDAccessType.PROPERTY,则必须为整个类指定默认行为。这就是为什么您需要在类级别使用AccessType.FIELD(尽管AccessType.FIELD 是默认值。)

现在,如果您在 phnnumber 字段中没有 @Transient,JPA 将为您提供一个 3 列的表:

身份证, phn 号, getphn 号码。

这是因为它会为所有实体字段(idphnnumber)使用AccessType.FIELD,同时,它会为你的 getter 使用AccessType.PROPERTYgetPhnnumber())。 您将以在数据库中映射两次的电话号码结束。

因此,@Transient 注释是必需的 - 这意味着实体不会将 field 的值存储在底层存储中,而是存储您的 getter 返回的值强>.

【讨论】:

默认不是FIELD。如果您在字段上放置映射注释,则访问类型为 FIELD,如果您在 getter 上放置映射注释,则访问类型为 PROPERTY。并且所有实体层次结构必须在映射注释放置中保持一致:总是在字段上,或者总是在 getter 上,但不能混合。 你是对的 - 默认值取决于 @Id 注释所在的位置。关于混合 - 您仅指 id 注释或您无法在实体层次结构中混合属性/字段访问的事实? 如果您没有明确指定访问类型,JPA 规范规定层次结构中的所有映射注释都必须放在字段或 getter 上。如果您不遵守规则会发生什么,但未指定。 Hibernate 查找 Id 注释的位置,如果它在字段上,它会忽略 getter 上的所有注释(反之亦然),但这是特定于 Hibernate 的。这种情况下的行为是未定义的(这就是规范所说的)。 我可以发誓我在“Pro JPA 2.0:掌握 Java 持久性”中读到了 @Id,但我只是检查了规范,它实际上根本没有谈论 Id;只是关于您提到的映射注释。感谢JB的澄清! 好吧,我刚发现书里是@Id,因为它是示例中唯一的映射注解...

以上是关于AccessType.FIELD、AccessType.PROPERTY 和 @Access 的用途是啥的主要内容,如果未能解决你的问题,请参考以下文章

Spring JPA:BaseEntity 未映射