it-roy-ru.com

В штучной упаковке против примитивного типа как идентификатор объекта

В JPA (реализация Hibernate) Какой тип лучше использовать в качестве идентификатора сущности: Тип в штучной упаковке (например, Integer) или Тип без коробок (например, int)?

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

Но id моих сущностей был int, и он работал нормально, без каких-либо ошибок, и мы знаем, что значением по умолчанию переменных примитива является 0. Поэтому он сказал, что, возможно, hibernate рассматривает 0 как особый и предполагает, что объект является новым.

20
Mahozad

Ну, мы используем не примитивы, и у нас есть для этого веские причины. Многие из наших полей, например int/Integer, имеют абсолютную бизнес-ценность zero, чтобы быть полностью действительными. Например, подумайте о поле долга - это более чем нормально, если поле zero, то есть у вас нет задолженности. 

Проблема в том, что с примитивами ноль является значением по умолчанию - так что вы можете случайно забыть установить его, например, с помощью setDebt, таким образом, он может достигнуть вашей базы данных со значением, которое вы никогда не намеревались использовать. По этой причине мы используем Integer с некоторыми проверками, которые никогда не должны быть нулевыми, например; но даже если мы забудем добавить правильные проверки, этот код потенциально нарушится с NullPointerException (желательно в тестах), и мне больше нравится Исключение, чем несовместимые значения в базе данных. 

7
Eugene

Кажется Текущая документациярекомендует использовать Boxed Type.

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

9
gtgaxiola

Нет разницы между примитивом (например, int) и его оболочкой (например, Integer) для идентификатора объекта. Оба действительны в соответствии со спецификацией JPA. JPA-провайдер достаточно умен, чтобы отслеживать состояние и жизненный цикл объекта. Когда идентификатор объекта равен 0 (тип примитива) или NULL (тип оболочки), поставщик JPA сгенерирует идентификатор для объекта, если настроен генератор идентификаторов. Ноль не считается действительным идентификатором объекта, если идентификатор генерируется автоматически.

Протестировал оба случая с Cmobilecom JPA, и он работает одинаково хорошо. Конечно, никакой разницы в производительности не замечено.

Отказ от ответственности: я являюсь разработчиком Cmobilecom JPA , легкой реализации JPA для Java и Android.

2
John

Уникальные идентификаторы сущностей и коллекций могут быть любого базового типа, кроме двоичного, BLOB-объекта и Clob. (Составные идентификаторы также допускаются, см. Ниже.)

Базовые типы значений имеют соответствующие константы типа, определенные в org.hibernate.Hibernate. Например, Hibernate.STRING представляет тип строки.

0
Angad Bansode

Я предпочитаю Boxed Type в модели сущностей, потому что это дает гибкость в использовании Boxed Type в обобщениях . Например, здесь модель Entity может иметь только тип, который расширяется до Serializable для id. Это будет полезно позже на уровне сервиса, где мы можем выполнять различные операции с первичным ключом.

public interface BaseEntity<E extends Serializable> extends Serializable {
  E getId();
}

Модель сущности может быть такой:

@Entity
public class PhoneNumber implements BaseEntity<Long> {
  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "PHONE_NUMBER_ID")
  private Long id;
0
pradipforever