Пустые конструкторы и сеттеры в JPA Entites - PullRequest
12 голосов
/ 22 июня 2009

Мне не нравится требование иметь хотя бы один пустой конструктор и открытые сеттеры для сущностей JPA. Хотя я понимаю проблему на стороне EntityManager, это делает недействительными инварианты классов.

У кого-нибудь есть решение для этого (шаблон проектирования или уровень идиома)?

Спасибо!

Игорь

Ответы [ 6 ]

17 голосов
/ 23 июня 2009

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

Следующий код будет использовать прямой доступ к полю и будет работать как часть сущности без установщика:

@Column(name = DESCRIPTION)
private String description;

public String getDescription() { return description; }

В зависимости от доступа к методу с помощью установщика:

private String description;

@Column(name = DESCRIPTION)
public void setDescription(String description) {
     this.description = description;
}

public String getDescription() { return description; }
6 голосов
/ 02 июля 2009

На самом деле вы должны иметь как конструктор без аргументов, так и методы получения и установки. Требования указаны в разделе 2.1 спецификации .

Требование конструктора без аргументов найдено на странице 17 в моей копии:

Класс сущности должен иметь без аргументов конструктор. Класс сущности может иметь и другие конструкторы. Без арг конструктор должен быть публичным или защищенный.

Страница 18 содержит требования к методам доступа:

Постоянное состояние объекта представлены переменными экземпляра, который может соответствовать Java-бобам свойства. Переменная экземпляра может быть доступным только изнутри методы организации по Сам экземпляр сущности. Пример переменные не должны быть доступны клиенты организации. Штат сущность доступна для клиентов только через средство доступа к объекту методы (методы получения / установки) или другие методы ведения бизнеса. Пример переменные должны быть приватными, защищенными, или видимость пакета.

Доступ к полю и собственности указывает, как поставщик JPA взаимодействует с вашей сущностью, а не как клиентское приложение взаимодействует с ней. Клиент всегда должен использовать методы get и set.

Некоторые поставщики JPA более снисходительны в этих требованиях, и вы можете сделать конструктор частным (как предложено выше) с конкретным поставщиком. Приложение может быть не переносимым, поэтому вы можете быть удивлены, если будете мигрировать в будущем.

Так что я бы не рекомендовал полностью опускать методы. Чтобы решить эту проблему, я бы пометил общедоступный no-arg ctor как устаревший (поместите что-то в javadoc о том, что это только для использования JPA-провайдером) Методы set могут содержать логику, которую вы хотите поддерживать ваши инварианты.

Это не идеально, но это должно предотвратить случайное использование неверного ctor (я предполагаю, что у вас есть ctor, который устанавливает инварианты).

3 голосов
/ 26 июня 2009

OpenJPA может добавить c-no-arg ctor как часть улучшения ваших сущностей.

Для ясности, требование указано в спецификации JPA. В предыдущем ответе говорится, что вы можете сделать приватный аргумент no-arg ctor, но это не соответствует спецификации (я вижу, что ссылка указывает на страницу Hibernate). В спецификации говорится, что у сущности должен быть общедоступный или защищенный безусловный ctor.

-Rick

2 голосов
/ 25 июня 2009

Просто сделайте ваш конструктор защищенным или закрытым, чтобы сохранить инварианты класса!

public class Person {
 private String firstName;
 private String lastName;

 public Person(String firstName, String lastName) {
  setFirstName(firstName);
  setLastName(lastName);
 }

 // private no-arg constructor for hibernate.
 private Person() {

 }

 public String getFirstName() {
  return firstName;
 }
 public String getLastName() {
  return lastName;
 }

 // private setters for hibernate
 private void setFirstName(String nme) {
  firstName = nme;
 }
 private void setLastName(String nme) {
  lastName = nme;
 }
}

Подробнее см. http://www.javalobby.org/java/forums/m91937279.html.

1 голос
/ 22 июня 2009

С DataNucleus вам не нужно добавлять конструктор по умолчанию, если вы этого не хотите; он будет добавлен автоматически улучшением байт-кода. Также вы можете сохранять поля вместо свойств, поэтому нет необходимости в открытых установщиках.

- Энди ( DataNucleus )

0 голосов
/ 23 июня 2009

Да, сохраняйте поля вместо свойств, но если вы не хотите использовать конструктор по умолчанию, вы, как правило (если только байт-код не выполняет какую-то хитрость), от этого не уйдете.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...