@Access

@Access определяет, через что JPA читает и записывает состояние сущности.

  • AccessType.FIELD — напрямую через поля;
  • AccessType.PROPERTY — через getter/setter.

Стратегия по умолчанию определяется местом @Id: на поле — field access, на getter — property access.

Field access

@Entity
@Access(AccessType.FIELD)
class Customer {
    @Id
    private Long id;
 
    private String name;
}

Провайдер не вызывает setter, поэтому бизнес-методы можно проектировать независимо. Маппинг относится к полям.

Property access

@Entity
@Access(AccessType.PROPERTY)
class Customer {
    private Long id;
 
    @Id
    public Long getId() {
        return id;
    }
 
    protected void setId(Long id) {
        this.id = id;
    }
}

Провайдер вызывает методы. В них нельзя бездумно помещать побочные эффекты или логику, которая изменяет другие поля.

Можно переопределить доступ для отдельного свойства, но смешанный маппинг сложнее читать.

Вопросы для повторения

  1. Как JPA выбирает доступ без @Access? По месту аннотации @Id.
  2. Можно ли разместить часть аннотаций на полях, часть на getter? Только с явным и понятным @Access; случайное смешивание непереносимо.
  3. Вызывает ли field access setter? Нет.
  4. Почему property access может быть опасен? Getter/setter могут иметь побочный эффект и вызываться провайдером не тогда, когда ожидает бизнес-код.

Связано: Основные аннотации Hibernate, Аннотация Transient.