Почему классы первичных ключей JPA-2.0 должны реализовывать Serializable, но мой пример работает без?

#persistence #jpa-2.0 #java

#постоянство #jpa-2.0 #java

Вопрос:

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

В моем примере (устаревшая база данных) существует взаимосвязь между employee и языками:

Класс Employee:

 @Entity
@IdClass(EmpleadoId.class)
@Table(name = "NO_INFGRAEMPL")
public class Empleado {    

  @Id
  @Column(name = "IGECOMPANIA", unique = true)
  private String compania;

  @Id
  @Column(name = "IGENUMEROIDENTIFIC", unique = true)
  private String numeroIdentificacion;

//...
}
  

Составной класс PrimaryKey сотрудника:

 public class EmpleadoId  {

  private String compania;
  private String numeroIdentificacion;
  //...         
}
  

Класс языковых навыков сотрудника:

 @Entity
@IdClass(IdiomaEmpleadoId.class)
@Table(name = "NO_IDIOMEMPLE")
public class IdiomaEmpleado {

  @Id
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumns(value = { 
      @JoinColumn(name= "IEMCOMPANIA", referencedColumnName = "IGECOMPANIA"), 
      @JoinColumn(name = "IEMEMPLEADO", referencedColumnName = "IGENUMEROIDENTIFIC")
      })
  private Empleado empleado;

  @Id
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "IEMIDIOMA")
  private Idioma idioma;

  @Column(name = "IEMNIVELLECTURA")
  private String nivelLectura;
//...
}
  

Владение языком сотрудника Составной класс PrimaryKey:

 public class IdiomaEmpleadoId {

  private EmpleadoId empleado;
  private String idioma;    

  //...    
}
  

Языковой класс:

 @Entity
@Table(name = "NO_IDIOMAS")    
public class Idioma {

  @Id
  @Column(name = "IDICODIGO")
  private String codigo;

  @Column(name = "IDIDESCRIPCION")
  private String descripcion;

//...
}
  

Я использую поставщик EclipseLink JPA2 в приложении J2SE, и это не дает мне никаких исключений.

Мои вопросы:

  • Почему это не дает мне исключений? Разве не обязательно иметь Serializable?
  • Безопасно ли продолжать таким образом или я должен обязательно реализовать serializable?.
  • В каких из них?, объектах JPA2 или классах PrimaryKey?

Большое спасибо за помощь.

Ответ №1:

Спецификация JPA содержит такое требование (JSR-317 раздел 2.4 Первичные ключи и идентификатор объекта):

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

Если EclipseLink действительно не обеспечивает выполнение этого требования, это деталь реализации EclipseLink, и я бы не рекомендовал вам полагаться на это.

Однако нет требований к сериализуемости объектов, за исключением следующего, который больше похож на рекомендацию, чем на требование:

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

Ответ №2:

Для сериализации ничего не требуется, но, похоже, это требуется спецификацией (от 10x до axtavt) для первичных ключей, хотя прямой необходимости в этом нет.

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

Ответ №3:

Классы первичного ключа должны реализовывать serializable, а класс composite-ID должен реализовывать serializable — это два разных вопроса. Я собираюсь ответить вам обоим и надеюсь, что это поможет вам различать и понимать целостно.

  1. Классы первичных ключей должны реализовывать serializable: Примечание: Это могло бы работать и без его ipleementation. Спецификация JPA содержит такое требование (раздел 2.4 JSR-317 Первичные ключи и идентификатор объекта):

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

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

  2. Класс Composite-ID должен реализовывать serializable. Идентификатор используется в качестве ключа для индексации загруженных объектов в сеансе. Объект сеанса должен быть сериализуемым, следовательно, все объекты, на которые он ссылается, также должны быть сериализуемыми. В случае CompositeIds в качестве идентификатора используется сам класс.