Можно ли иметь неизменные поля в Hibernate / JPA? - PullRequest
17 голосов
/ 29 октября 2011

В нашем приложении нам нужно иметь поля, которые можно назначать только один раз.

Сначала мы думали об инкапсуляции полей и о том, что сеттеры должны быть приватными.Однако возникают некоторые вопросы:

  • Без общедоступного установщика, может ли Hibernate по-прежнему отображать поле из базы данных?
  • Можно ли удалить установщик и сделать поле изменяемым тольков конструкторе сущностей?
  • Наконец, есть ли какой-нибудь стандартный способ JPA сделать поле неизменным?

Заранее спасибо.

Ответы [ 5 ]

15 голосов
/ 29 октября 2011
  • Ad. 1: Я считаю, что JPA использует простые приватные поля для чтения и записи, если аннотации размещаются на полях, а не на получателях. Недавно я обнаружил, что Hibernate как основной поставщик JPA даже не нуждается в методах get*() и set*(). Это было действительно поучительное решение, так как с самого начала я думал, что Hibernate требует доступа. Итак, ответ: вам не нужны сеттеры в отношении Hibernate.

  • Ad. 2: Однако обратите внимание, что Hibernate по-прежнему нуждается в конструкторе без аргументов, иначе он не сможет загрузить сущности с описательным исключением. Это также требование JPA.

  • Ad. 3: нет, нет. Помните, что ваши коллекции также должны были быть неизменными.

11 голосов
/ 30 октября 2011

Попробуйте

@Column(updatable = false)

И сделайте ваш сеттер приватным.(Оставьте ваш получатель открытым, если хотите)

Я думаю, что это лучшая практика.

PS: JPA использует доступ к полям, если вы аннотируете свои поля, и доступ к получателям / установщикам, если вы комментируетеметод получения.

3 голосов
/ 29 октября 2011

В JPA 2.0 у вас есть два способа определить, какие атрибуты должны быть сохранены:

  1. Доступ (FIELD) - имя поля сохраняется,
  2. Доступ (PROPERTY) -имя свойства сохраняется.

Если аннотация Access (-) не используется, решение о том, какой доступ будет использоваться, зависит от того, куда вы поместили аннотацию @Id.Если вы поместите его рядом с вашим полем - будет использоваться Access (FIELD).Если вы поместите его рядом со своим аксессором - будет использован Access (PROPERTY).

Поэтому, если вы используете Access (FIELD), вам не нужно иметь соответствующий аксессор в стиле JavaBeans для определенного поля.У вас может быть личное поле с именем «myField» и открытый сеттер для него с именем «public setBlahBlah (-)».JPA будет сохраняться только как «myField».

2 голосов
/ 06 июля 2013

Попробуйте

@Column(updatable = false)

Из javadoc:

Включен ли столбец в операторы SQL UPDATE, сгенерированные поставщиком постоянства.

1 голос
/ 29 октября 2011

Вы можете пометить объект аннотациями @Entity(mutable=false) или @Immutable для платформы, чтобы использовать этот факт для повышения производительности при кэшировании и тому подобном. (Hibernate)

Тогда вы можете использовать неизменяемый класс-обёртку, как этот:

public class ImmutableStuff {
    private final FooField barValue;

    public ImmutableStuff(Stuff stuff) {
        barValue = stuff.barValue;
    }

    public FooField getBarValue(){
        return barValue;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...