AccessType.FIELD、AccessType.PROPERTY和@Access的目的是什么?

72

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

而且,使用混合级别注释有什么目的,比如:

@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";
    }

}

这个班级到底在讲些什么?


请参阅优秀的比较讨论:https://dev59.com/BHRB5IYBdhLWcg3wiHv7 - Grigory Kislin
1个回答

97

默认情况下,访问类型由映射注释的放置位置定义。如果您将其放在字段上,则为AccessType.FIELD,如果您将其放在getter上,则为AccessType.PROPERTY

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

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

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

  • id,
  • phnnumber,
  • getphnnumber。

这是因为它将对所有实体字段(idphnnumber)使用AccessType.FIELD,同时它将为您的getter(getPhnnumber())使用AccessType.PROPERTY
这将导致电话号码在数据库中映射两次。

因此,需要@Transient注释 - 这意味着实体不会存储底层存储中的字段值,而是存储您的getter返回的值。


18
默认值不是FIELD。如果您在字段上放置映射注释,则访问类型为FIELD,如果您在getter上放置映射注释,则为PROPERTY。并且所有实体层次结构在映射注释放置方面必须保持一致:始终在字段上或始终在getter上,但不能混合使用。 - JB Nizet
2
你是对的 - 默认值取决于 @Id 注解的位置。关于混合 - 你是指仅限于 id 注解还是指在实体层次结构中根本不能混合属性/字段访问? - Piotr Nowicki
6
如果您没有明确指定访问类型,JPA规范规定层次结构中的所有映射注释必须放置在字段上或者getter方法上。但如果不遵守此规则会发生什么是未指定的。Hibernate查找@Id注释所在的位置,如果在字段上,则忽略getter方法上的所有注释(反之亦然),但这是Hibernate特有的行为。在这种情况下的行为是未定义的(这是规范所说的)。 - JB Nizet
1
好的,我刚刚发现在这本书中它是 @Id,因为它是示例中唯一的映射注释... - Piotr Nowicki
1
也许有点晚了,但是@PiotrNowicki,如果你得出结论认为id注释的位置无关紧要,那么也许你可以从你的答案中删除有关id注释位置的部分。 - T3rm1
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接