¿Cuándo y por qué las entidades JPA deberían implementar la interfaz serializable?

151

La pregunta está en el título. A continuación, acabo de describir algunos de mis pensamientos y hallazgos.

Cuando tenía un modelo de dominio muy simple (3 tablas sin ninguna relación), todas mis entidades NO implementaban Serializable.

Pero cuando el modelo de dominio se volvió más complejo, obtuve RuntimeException que decía que una de mis entidades no implementó Serializable.

Yo uso Hibernate como una implementación JPA.

Me pregunto:

  1. ¿Es un requisito / comportamiento específico del proveedor?
  2. ¿Qué pasa con mis entidades serializables? ¿Deben ser serializables para almacenar o transferir?
  3. ¿En qué momento es necesario hacer que mi entidad sea serializable?
romano
fuente

Respuestas:

59

Esto suele suceder si combina HQL y consultas SQL nativas. En HQL, Hibernate asigna los tipos que pasa a lo que sea que el DB entienda. Cuando ejecuta SQL nativo, debe hacer la asignación usted mismo. Si no lo hace, la asignación predeterminada es serializar el parámetro y enviarlo a la base de datos (con la esperanza de que lo entienda).

Aaron Digulla
fuente
Esto no explica por qué simplemente "tal vez cómo". Vea la respuesta a continuación de Bozho
chrips
¿Es esa entidad media se guardará en DB sin implementar la interfaz serializable?
Hanumantha_3048092
@ Hanumantha_3048092 Sí. Mapeo de entidades y Serializableson dos conceptos diferentes.
Aaron Digulla
@AaronDigulla ¿Puede explicarlo con un ejemplo o pseudocódigo?
sdindiver
110

De acuerdo con las especificaciones JPA:

Si una instancia de entidad se va a pasar por valor como un objeto separado (por ejemplo, a través de una interfaz remota), la clase de entidad debe implementar la interfaz serializable.

"JSR 220: Enterprise JavaBeansTM, Versión 3.0 Java Persistence API Versión 3.0, Versión final 2 de mayo de 2006"

Conor
fuente
14
(+1) mirar las especificaciones siempre es fructífero
Bozho
20
No veo por qué esto tiene tantos votos positivos. El OP dice que no era necesario cuando el modelo era más simple. Enviar los objetos de forma remota a través de la serialización de Java SIEMPRE requeriría que los objetos sean serializables, independientemente de su complejidad. Obviamente este no es el caso de uso del OP.
Robin
No estoy muy seguro sobre la hibernación, pero con otros proveedores de JPA hay operaciones que requieren que el proveedor haga una copia de una entidad (objeto). Serializablepodría ser útil con eso, y en el contexto de persistencia más consistente que, Cloneablepor ejemplo.
JimmyB
Esta respuesta es solo un volcado de información y no ayuda a nadie a entender por qué.
Chips
59

Necesita que sean sus entidades Serializablesi necesita transferirlas por cable (serializarlas a otra representación), almacenarlas en una sesión http (que a su vez serializa en el disco duro mediante el contenedor de servlets), etc.

Solo por persistencia, Serializableno es necesario, al menos con Hibernate. Pero es una buena práctica hacerlos Serializable.

Bozho
fuente
2
No sé, tal vez mis entidades se están transfiriendo implícitamente a alguna parte. Yo uso hibernate + spring + jsf y Tomcat. ¿En qué parte de esta cadena se puede realizar la transferencia?
Roman
@Roman, por ejemplo, el usuario actual (que puede ser una entidad) y todas sus entidades relacionadas pueden terminar en la sesión, que, como dice Bozho, puede ser serializada en el disco por el contenedor de servlets.
OrangeDog
¡Esta es la mejor respuesta "por qué y cuándo"! ¡Claro! Gracias
chrips
13

De acuerdo con los documentos de hibernación , al usar la anotación @JoinColumn:

Tiene uno más parámetros nombrados referencedColumnName. Este parámetro declara la columna en la entidad de destino que se usará para la unión. Tenga en cuenta que cuando se utiliza referencedColumnNameuna columna de clave no primaria, la clase asociada tiene que ser Serializable.

aman maharjan
fuente
8

Para complementar la buena respuesta de Conor que se refirió a las especificaciones JSR-317. Por lo general, los proyectos EAR consisten en un módulo EJB con los EJB expuestos a través de una interfaz remota. En este caso, debe hacer que sus beans de entidad sean serializables, ya que se agregan en el EJB remoto y se crean para conectarse a través de la red.

Un proyecto de guerra JEE6 sin CDI: puede contener EJB lite respaldado por entidades JPA no serializables.

Un proyecto de guerra JEE6 con CDI: los beans que usan el alcance de sesión, aplicación o conversación deben ser serializables, pero los beans que usan el alcance de la solicitud no tienen que ser serializables. Por lo tanto, los beans de entidad JPA subyacentes -si los hay- seguirían la misma semántica.

Sym-Sym
fuente
7

Si solo hablamos de persistencia, Serializableno es necesario Pero es la mejor práctica hacer las entidades Serializable.

Si estamos exponiendo domain/ entitiesobjetos directamente expuestos a la capa de presentación, en lugar de usar DTO, en ese caso necesitamos implementar Serializable. Estos objetos de dominio se pueden almacenar con HTTPSessionfines de almacenamiento en caché / optimización. Una sesión http puede ser serializada o agrupada. Y también es necesario para transferir datos entre JVMinstancias.

Cuando usamos DTOpara desacoplar la capa de persistencia y la capa de servicio, marcar los objetos del dominio como Serializablecontraproducentes y violaría el " encapsulation". Entonces se convierte en un antipatrón.

Identificadores compuestos

La clase de clave primaria debe ser serializable.

Modelos POJO

Si una instancia de entidad se va a utilizar de forma remota como un objeto separado, la clase de entidad debe implementar la Serializableinterfaz.

Caché
Además, si está implementando un clusteredsegundo nivel, cacheentonces sus entidades deben serlo serializable. El identificador debe ser Serializableporque es un requisito de JPA, ya que identifierpodría usarse como la clave para una entrada de caché de segundo nivel.

Y cuando serializamos entidades, asegúrese de proporcionar un serialVersionUIDmodificador de acceso privado explícito . Porque si una serializableclase no declara explícitamente a serialVersionUID, entonces el tiempo de ejecución de serialización calculará un serialVersionUIDvalor predeterminado para esa clase en función de varios aspectos de la clase, como se describe en la Especificación de serialización de objetos Java (TM). El serialVersionUIDcálculo predeterminado es muy sensible a los detalles de la clase que pueden variar según las implementaciones del compilador y, por lo tanto, pueden resultar inesperados InvalidClassExceptionsdurante la deserialización.

Ankur Singhal
fuente
6

Creo que su problema está relacionado con tener un campo de un tipo complejo (clase) que no está anotado. En tales casos, el manejo predeterminado será almacenar el objeto en su forma serializada en la base de datos (lo que probablemente no sea lo que pretendía hacer) Ejemplo:

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

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

En el caso anterior, CustomerData se guardará en un campo de matriz de bytes en la base de datos en su forma serializada.

Avner Levy
fuente
5

Especificación JPA

De acuerdo con la especificación JPA, una entidad debe implementarse Serializablesolo si necesita pasar de una JVM a otra o si la entidad es utilizada por un bean de sesión con estado que necesita ser pasivado por el contenedor EJB.

Si una instancia de entidad se va a pasar por valor como un objeto separado (por ejemplo, a través de una interfaz remota), la clase de entidad debe implementar la Serializableinterfaz.

Hibernar

Hibernate solo requiere que los atributos de la entidad sean Serializable, pero no la entidad misma.

Sin embargo, al implementar la especificación JPA, todos los requisitos de JPA con respecto a las Serializableentidades también se aplican a Hibernate.

Gato

Según la documentación de Tomcat , los HttpSessionatributos también deben ser Serializable:

Cada vez que Apache Tomcat se apaga normalmente y se reinicia, o cuando se activa la recarga de una aplicación, la implementación estándar del Administrador intentará serializar todas las sesiones activas actualmente en un archivo de disco ubicado a través del atributo pathname. Todas estas sesiones guardadas se deserializarán y activarán (suponiendo que no hayan expirado en el tiempo medio) cuando se complete la recarga de la aplicación.

Para restaurar con éxito el estado de los atributos de la sesión, todos estos atributos DEBEN implementar la interfaz java.io.Serializable.

Por lo tanto, si la entidad se almacena en el HttpSession, debe implementar Serializable.

Vlad Mihalcea
fuente
4

Las clases deben implementar Serializable si desea serializarlas. Esto no está directamente relacionado con JPA y la especificación JPA no requiere que las entidades sean serializables. Si Hibernate realmente se queja de esto, supongo que es un error de Hibernate, pero supongo que directa o indirectamente está haciendo algo más con las entidades, lo que requiere que sean serializables.

jarnbjo
fuente
3

Consulte http://www.adam-bien.com/roller/abien/entry/do_jpa_entities_have_to dice, La implementación de java.io.Serializable es simplemente necesaria para transferir datos a través de IIOP o JRMP (RMI) entre instancias JVM. En el caso de una aplicación web pura, los objetos de dominio a veces se almacenan en HTTPSession para fines de almacenamiento en caché / optimización. Una sesión http puede ser serializada (pasivación) o agrupada. En ambos casos, todo el contenido debe ser serializable.

Arun K
fuente
1

el golpe remoto usando cartero o ajax o angular js, etc ....., puede causar la repetición del ciclo con la excepción StackOverflow con Jackson más rápidoxml. Por lo tanto, es mejor usar serializador.

tamil
fuente
1
  1. ¿En qué momento es necesario hacer que mi entidad sea serializable?

La implementación de ehcache con el almacén de discos como caché de segundo nivel (es decir, utilizando @Cacheableanotaciones en la entidad o en el método de repositorio / servicio) requiere Serializable; de ​​lo contrario, la caché fallará ( NotSerializableException) al escribir la entidad en la caché de disco.

Michal
fuente
0

Este es también el error que se produce cuando pasa una ID incorrectamente escrita como el segundo parámetro a algo como em.find () (es decir, pasa la entidad en lugar de su ID). Todavía no he encontrado necesario declarar las entidades JPA serializables: no es realmente necesario a menos que esté usando el nombre de columna referenciado como lo describe aman.

Amalgovinus
fuente
0

cuando las entidades JPA se utilizan como parámetros o valores de retorno por las operaciones EJB remotas

SAR
fuente