Вопрос-ответ

Hibernate Annotations - Which is better, field or property access?

Аннотации гибернации - Что лучше, доступ к полю или свойству?

Этот вопрос в некоторой степени связан с вопросом о размещении аннотаций гибернации.

Но я хочу знать, что лучше? Доступ через свойства или доступ через поля? Каковы преимущества и недостатки каждого из них?

Переведено автоматически
Ответ 1

Есть аргументы в пользу обоих, но большинство из них вытекают из определенных требований пользователя "Что, если вам нужно добавить логику для", или "xxxx нарушает инкапсуляцию". Однако никто толком не прокомментировал теорию и не привел должным образом аргументированных аргументов.

Что на самом деле делает Hibernate / JPA, когда сохраняет объект - ну, это сохранение СОСТОЯНИЯ объекта. Это означает сохранение его таким образом, чтобы его можно было легко воспроизвести.

Что такое инкапсуляция? Инкапсуляция означает инкапсуляцию данных (или состояния) с помощью интерфейса, который приложение / клиент может использовать для безопасного доступа к данным, сохраняя их согласованность и валидность.

Представьте это как MS Word. MS Word поддерживает модель документа в памяти - состояние документов. Он представляет интерфейс, который пользователь может использовать для изменения документа - набор кнопок, инструментов, команд клавиатуры и т.д. Однако, когда вы сохраняете (сохраняете) этот документ, он сохраняет внутреннее состояние, а не набор нажатий клавиш и щелчков мыши, использованных для его создания.

Сохранение внутреннего состояния объекта НЕ нарушает инкапсуляцию - в противном случае вы на самом деле не понимаете, что означает инкапсуляция и почему она существует. На самом деле это похоже на сериализацию объектов.

По этой причине В БОЛЬШИНСТВЕ СЛУЧАЕВ целесообразно сохранять ПОЛЯ, а не СРЕДСТВА ДОСТУПА. Это означает, что объект может быть точно воссоздан из базы данных в том виде, в каком он был сохранен. Это не должно нуждаться в какой-либо проверке, потому что это было сделано в оригинале при его создании и до того, как он был сохранен в базе данных (если, не дай Бог, вы не храните недопустимые данные в БД !!!!). Аналогично, не должно быть необходимости вычислять значения, поскольку они уже были вычислены до сохранения объекта. Объект должен выглядеть точно так же, как он выглядел до сохранения. Фактически, добавляя дополнительные элементы в средства получения / установки, вы на самом деле увеличиваете риск того, что вы воссоздадите что-то, что не является точной копией оригинала.

Конечно, эта функциональность была добавлена не просто так. Могут быть некоторые допустимые варианты использования для сохранения средств доступа, однако, как правило, они будут редкими. Примером может быть то, что вы хотите избежать сохранения вычисляемого значения. Однако вы можете захотеть задать вопрос, почему вы не вычисляете это по требованию в методе получения значения или лениво инициализируете это в методе получения. Лично я не могу придумать ни одного хорошего варианта использования, и ни один из приведенных здесь ответов на самом деле не дает ответа "Программная инженерия".

Ответ 2

Я предпочитаю доступ к полю, потому что таким образом я не вынужден предоставлять метод получения / установки для каждого свойства.

Быстрый опрос через Google показывает, что доступ к полю составляет большинство (например, http://java.dzone.com/tips/12-feb-jpa-20-why-accesstype).

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

Есть связанный с SO вопрос, который пытался измерить производительность и пришел к выводу, что "разницы нет".

Ответ 3

Вот ситуация, когда вам приходится использовать средства доступа к свойствам. Представьте, что у вас есть универсальный абстрактный класс с большим количеством возможностей реализации для наследования в 8 конкретных подклассов:

public abstract class Foo<T extends Bar> {

T oneThing;
T anotherThing;

// getters and setters ommited for brevity

// Lots and lots of implementation regarding oneThing and anotherThing here
}

Теперь точно, как вы должны аннотировать этот класс? Ответ заключается в том, что вы ВООБЩЕ НЕ МОЖЕТЕ аннотировать его ни с помощью доступа к полю, ни с помощью доступа к свойству, потому что вы не можете указать целевую сущность на этом этапе. Вы ДОЛЖНЫ аннотировать конкретные реализации. Но поскольку сохраняемые свойства объявлены в этом суперклассе, вы ДОЛЖНЫ использовать доступ к свойствам в подклассах.

Доступ к полю невозможен в приложении с абстрактными универсальными суперклассами.

Ответ 4

Я предпочитаю использовать средства доступа к свойствам:


  • Я могу добавить логику, если возникнет необходимость (как указано в принятом ответе).

  • это позволяет мне вызывать foo.getId() без инициализации прокси (важно при использовании гибернации, пока не будет разрешен HHH-3718).

Недостаток:


  • это делает код менее читабельным, вам приходится, например, просматривать весь класс, чтобы увидеть, есть ли там @Transient.

java hibernate jpa