24. Для чего нужна аннотация @Access?

24. Для чего нужна аннотация @Access?

UNKNOWN

Hibernate  или  другой  провайдер  должен  каким-то  образом  получать  доступ  к полям сущности. Например, при сохранении сущности в базу данных Hibernate должен получить доступ к состоянию сущности, то есть прочитать значения полей сущности, чтобы  записать  их  в  соответствующие  ячейки  таблицы.

Аналогично  при  получении данных из БД и формировании из них объекта сущности, Hibernate должен создать этот самый объект сущности (для этого ему и нужен public или protected конструктор без параметров), а затем записать в поля этого объекта значения, полученные из ячеек БД, тем самым сформировав состояние сущности. Для чтения и записи этих полей Hibernate использует два подхода:

  1. Field access  (доступ  по  полям).  При  таком  способе  аннотации  маппинга  (Id, Column,  OneToMany,  …  )  размещаются  над  полями,  и  Hibernate  напрямую работает с полями сущности, читая и записывая их.
  2. Property access  (доступ  по  свойствам).  При  таком  способе  аннотации размещаются  над  методами-геттерами,  но никак  не  над сеттерами.  Hibernate использует  их  и  сеттеры  для  чтения  и  записи  полей  сущности.  Но  есть требование  -  у  сущности  с  property  access  названия  методов  должны соответствовать требованиям JavaBeans. Например, если у сущности Customer есть  поле  с  именем  firstName,  то  у  этой  сущности  должны  быть  определены методы getFirstName и setFirstName для чтения и записи поля  firstName.

Совокупность полей и методов (свойств) сущности называется атрибутами.

Эти  два  подхода  неявно  определяют  тип  доступа  к  состоянию  конкретной сущности  -  либо  доступ  по  полям  либо  доступ  по  свойствам.  Но  при  неявном определении типа доступа JPA требует, чтобы у всех сущностей в иерархии был единый тип доступа.

По  умолчанию  тип  доступа  определяется  местом,  в  котором  находится аннотация  @Id.  Если  она  будет  над  полем  -  это  будет  AccessType.FIELD,  если  над геттером - это AccessType.PROPERTY.

Чтобы явно определить тип доступа у сущности, нужно использовать аннотацию @Access, которая может быть указана у сущности, Mapped Superclass и Embeddable class, а также над полями или методами.

Аннотация @Access позволяет в иерархии сущностей с одним единым типом доступа безболезненно определить для одной или нескольких сущностей другой тип доступа. То есть в иерархии, где у всех тип доступа, например, field access, можно у какой-нибудь сущности указать тип доступа property access и это не нарушит работу Hibernate.

Если у сущности объявлена аннотация @Access(AccessType.FIELD):

  • значит аннотации маппинга нужно размещать над полями;
  • есть возможность у любых атрибутов сущности поменять тип доступа на property access,  разместив  аннотацию  @Access(AccessType.PROPERTY)  над соответствующими геттерами;
  • разместив  аннотации  маппинга  над  методами,  не  имеющими @Access(AccessType.PROPERTY), получим неопределенное поведение.

Если у сущности объявлена аннотация @Access(AccessType.PROPERTY):

  • значит аннотации маппинга нужно размещать над геттерами;
  • есть возможность у любых атрибутов сущности поменять тип доступа на field access,  разместив  аннотацию  @Access(AccessType.FIELD)  над соответствующими полями;
  • разместив  аннотации  маппинга  над  полями,  не  имеющими @Access(AccessType.FIELD), получим неопределенное поведение.

Поля, унаследованные от суперкласса, имеют тип доступа этого суперкласса, а не дочерней сущности, даже если они не совпадают.

Когда  у  одной  сущности  определены  разные  типы  доступа,  то  нужно использовать аннотацию @Transient для избежания дублирования маппинга.


Предыдущий вопрос: 23. Для чего нужна аннотация @Column?

Следующий вопрос: 25. Для чего нужна аннотация @Cacheable?

Все вопросы по теме: список

Все темы: список

Вопросы/замечания/предложения/нашли ошибку: напишите мне

Report Page