Статьи

Шаблоны реализации JPA: доступ к полю или доступ к свойству

Я продолжу серию шаблонов реализации JPA , обсуждая относительные преимущества доступа к полям и доступа к свойствам.

Спецификация JPA разрешает провайдеру постоянства два способа доступа к постоянному состоянию объекта. Поставщик персистентности может либо вызывать средства доступа к свойствам стиля JavaBeans (методы получения и установки), либо напрямую обращаться к полям экземпляра объекта. Какой метод используется, зависит от того, аннотировали ли вы свойства или поля объекта.

Спецификация JPA 1.0 не позволяет вам смешивать типы доступа внутри объекта или даже в иерархии объектов. Если вы аннотировали поля и свойства, поведение не определено. Спецификация JPA 2.0 имеет аннотацию @Access, которая позволяет смешивать типы доступа внутри объекта или иерархии объектов .

Но интересный вопрос остается; какой тип доступа использовать? Вопрос, который обсуждался ранее , но я не удержался и от комментариев.;-)

  • Инкапсуляция — считается, что доступ к свойству обеспечивает лучшую инкапсуляцию, потому что прямой доступ к полям плох, не так ли? На самом деле, использование доступа к свойствам обязывает вас писать методы получения и установки для всех ваших постоянных свойств. Эти методы не только позволяют провайдеру JPA устанавливать поля, они также позволяют любому другому пользователю вашего класса сущности делать это! Использование доступа к полю позволяет вам записывать только те геттеры и сеттеры, которые вы хотите ( они злые , помните?), А также записывать их так, как вы хотите, например, выполняя проверку в ваших сеттерах или некоторые вычисления в ваших геттерах. Напротив, умение делать эти методы при использовании доступа к свойствам просто создает проблемы .
  • Производительность — Некоторые люди предпочитают доступ к полям, потому что он предположительно предлагает лучшую производительность, чем доступ к свойствам. Но это очень плохая причина для выбора доступа к полю. Современные оптимизирующие JVM обеспечат доступ к свойству так же быстро, как и доступ к полю, и в любом случае вызовы базы данных на несколько порядков медленнее, чем доступ к полю или вызов метода.
  • Ленивая загрузка в Hibernate — реализация отложенной загрузки Hibernate всегда инициализирует отложенный прокси при вызове любого метода на этом прокси. Единственным исключением является метод, помеченный аннотацией @Id при использовании доступа к свойству. Но когда вы используете доступ к полю, такого метода нет, и Hibernate инициализирует прокси даже при вызове метода, который возвращает идентичность объекта. Хотя некоторые предлагают использовать доступ к свойствам до тех пор, пока эта ошибка не будет исправлена, я не сторонник принятия проектных решений на основе ошибок инфраструктуры. Если эта ошибка действительно ухудшает вашу производительность, вы можете попытаться получить идентификатор объекта с помощью следующего кода:
    Serializable id = ((HibernateProxy) entity).getHibernateLazyInitializer().getIdentifier()
     

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

  • Доступ к полям в Hibernate. Полезно знать, что, хотя Hibernate допускает доступ к полям для заполнения ваших объектов, ваш код все равно должен получать доступ к этим значениям с помощью методов. В противном случае вы попадете в первую из ловушек прокси Hibernate, упомянутую моим коллегой Маартеном Винкелсом.

Подводя итог, я думаю, что доступ к полям — это путь, потому что он предлагает лучшую инкапсуляцию (без этого невозможно должное управление двунаправленными связями), а влияние на производительность незначительно (# 1 в проблемах с производительностью топ-10 по-прежнему является взаимодействием между базой данных и вашим Java-приложение). Единственный недостаток — некоторые snafu в реализации отложенной загрузки Hibernate, которые требуют особой осторожности при использовании полевого доступа.

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

С http://blog.xebia.com