本文深入解析 jpa 的 `@access` 注解如何在单个字段上覆盖默认访问策略,通过 `accesstype.field` 与 `accesstype.property` 混用实现细粒度控制,并提供可验证的单元测试证明其行为差异。
在 JPA 规范中,实体的默认访问类型(Access Type)由 @Id 注解的位置决定:若 @Id 标注在字段上(如 private Long ID;),则整个实体默认采用 AccessType.FIELD —— 即 JPA 直接通过反射读写字段值,完全绕过 getter/setter 方法;反之,若 @Id 标注在 getter 上,则默认为 AccessType.PROPERTY,JPA 会通过属性访问器(getter/setter)操作数据。
但 @Access 注解的强大之处在于它支持字段级覆盖。你可以在任意非 @Id 字段上显式声明 @Access(AccessType.PROPERTY),强制 JPA 对该字段改用 getter/setter 访问,即使其他字段仍走字段直读模式。这正是你示例中 lastName 字段的行为基础:
@Access(value = AccessType.PROPERTY) private String lastName; // ← 此字段将通过 getLastName()/setLastName() 访问
而 firstName 未加 @Access,且实体整体为 FIELD 模式,因此 JPA 不会调用 getFirstName() 或 setFirstName() —— 它直接读写 firstName 字段本身。这也是你日志未触发的关键原因。
✅ 验证逻辑如下: