Когда и почему сущности JPA должны реализовывать интерфейс Serializable? - PullRequest
117 голосов
/ 07 января 2010

Вопрос в названии. Ниже я только что описал некоторые свои мысли и выводы.

Когда у меня была очень простая модель предметной области (3 таблицы без каких-либо отношений), все мои объекты НЕ реализовывали Serializable.

Но когда доменная модель стала более сложной, я получил RuntimeException, в котором говорилось, что один из моих объектов не реализовал Serializable.

Я использую Hibernate в качестве реализации JPA.

Интересно:

  1. Это специфичное для поставщика требование / поведение?
  2. Что происходит с моими сериализуемыми сущностями? Должны ли они быть сериализуемыми для хранения или передачи?
  3. В какой момент становится необходимым сделать мою сущность сериализуемой?

Ответы [ 12 ]

104 голосов
/ 07 января 2010

Согласно спецификации JPA:

Если экземпляр сущности должен передаваться по значению как отдельный объект (например, через удаленный интерфейс), класс сущности должен реализовывать интерфейс Serializable.

"JSR 220: Enterprise JavaBeansTM, версия 3.0 API персистентности Java версии 3.0, финальная версия 2 мая 2006 г."

50 голосов
/ 07 января 2010

Обычно это происходит, если вы смешиваете HQL и нативные SQL-запросы. В HQL Hibernate сопоставляет передаваемые вами типы с тем, что понимает БД. Когда вы запускаете собственный SQL, то вы должны выполнить отображение самостоятельно. Если вы этого не сделаете, то по умолчанию сопоставление заключается в сериализации параметра и его отправке в базу данных (в надежде, что он это понимает).

45 голосов
/ 07 января 2010

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

Просто ради настойчивости Serializable не нужен, по крайней мере, в Hibernate. Но лучше всего делать их Serializable.

8 голосов
/ 29 октября 2012

В дополнение к приятному ответу Конора, который ссылался на спецификации JSR-317. Как правило, проекты EAR состоят из модуля EJB с EJB, предоставляемыми через удаленный интерфейс. В этом случае вам нужно сделать сериализованные компоненты управления данными компонентными, так как они агрегированы в удаленном EJB-компоненте и предназначены для проводного соединения по сети.

Военный проект JEE6 без CDI: может содержать EJB lite, поддерживаемый несериализуемыми сущностями JPA.

Проект войны JEE6 с CDI: Бины, использующие область сеанса, приложения или диалога, должны быть сериализуемыми, но бины, использующие область запроса, не должны быть сериализуемыми. Таким образом, базовые бины сущности JPA - если таковой имеется - будет следовать той же семантике.

6 голосов
/ 09 апреля 2017

Согласно документам гибернации при использовании аннотации @JoinColumn:

У него есть еще один параметр с именем referencedColumnName. Этот параметр объявляет столбец в целевом объекте, который будет использоваться для объединения. Обратите внимание, что при использовании referencedColumnName для столбца без первичного ключа связанный класс должен быть Serializable.

6 голосов
/ 09 сентября 2012

Я считаю, что ваша проблема связана с наличием поля сложного типа (класса), которое не аннотировано. В таких случаях обработка по умолчанию будет хранить объект в его сериализованной форме в базе данных (что, вероятно, не то, что вы хотели сделать) Пример:

Class CustomerData {
    int getAge();
    void setAge(int age);
}

@Entity
Class Customer {
  CustomerData getCustomerData();
  void setCustomerData(CustomerData data)
}

В указанном выше случае CustomerData будет сохранен в поле байтового массива в базе данных в его сериализованной форме.

4 голосов
/ 07 января 2010

Классы должны реализовывать Serializable, если вы хотите их сериализовать. Это не имеет прямого отношения к JPA, и спецификация JPA не требует, чтобы объекты были сериализуемыми. Если Hibernate действительно жалуется на это, я предполагаю, что это ошибка Hibernate, но я предполагаю, что вы прямо или косвенно делаете что-то еще с объектами, которые требуют их сериализации.

3 голосов
/ 26 сентября 2018

Пожалуйста, обратитесь http://www.adam -bien.com / roller / abien / entry / do_jpa_entities_have_to это говорит, Реализация java.io.Serializable просто необходима для передачи данных через JOPM-экземпляры через IIOP или JRMP (RMI). В случае чистого веб-приложения доменные объекты иногда хранятся в HTTPSession для целей кэширования / оптимизации. Http-сессия может быть сериализована (пассивироваться) или кластеризована. В обоих случаях все содержимое должно быть сериализуемым.

1 голос
/ 30 марта 2019

Если мы просто говорим о настойчивости, Serializable не нужен, но лучше всего делать сущности Serializable.

Если мы выставляем domain / entities объекты, непосредственно представленные на уровне представления, вместо использования DTO, в этом случае нам нужно реализовать Serializable. Эти доменные объекты могут храниться в HTTPSession для целей кэширования / оптимизации. Http-сессия может быть сериализована или сгруппирована. И это также требуется для передачи данных между JVM -экземплярами.

Когда мы используем DTO для разделения персистентного слоя и сервисного уровня, пометка доменных объектов как Serializable будет контрпродуктивной и нарушит «encapsulation». Тогда это становится анти-паттерном.

Составные идентификаторы

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

POJO Models

Если экземпляр сущности должен использоваться удаленно как отдельный объект, класс сущностей должен реализовывать интерфейс Serializable.

Cache
Кроме того, если вы реализуете clustered второй уровень cache, тогда ваши сущности должны быть serializable. Идентификатор должен быть Serializable, поскольку это требование JPA, поскольку identifier может использоваться в качестве ключа для записи в кэш второго уровня.

И когда мы сериализуем сущности, обязательно предоставим явный serialVersionUID с модификатором частного доступа. Потому что если класс serializable явно не объявляет serialVersionUID, то среда выполнения сериализации вычислит значение serialVersionUID по умолчанию для этого класса на основе различных аспектов класса, как описано в Спецификации сериализации объектов Java (TM). Вычисления по умолчанию serialVersionUID очень чувствительны к деталям класса, которые могут различаться в зависимости от реализаций компилятора, и, следовательно, могут привести к неожиданному InvalidClassExceptions во время десериализации.

1 голос
/ 13 октября 2017

удаленное попадание с использованием почтальона, ajax или углового js и т. Д. ....., может вызвать цикл повторения с исключением StackOverflow с Джексоном быстрее xml. Поэтому лучше использовать сериализатор.

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