2010-01-07 14 views
85

La pregunta está en el título. A continuación, describí algunos de mis pensamientos y hallazgos.¿Cuándo y por qué las entidades JPA deberían implementar una interfaz Serializable?

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

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

Utilizo Hibernate como una implementación de JPA.

me pregunto:

  1. Es requisito específico del proveedor/comportamiento?
  2. ¿Qué sucede con mis entidades serializables? ¿Deberían ser serializables para almacenar o transferir?
  3. ¿En ese momento es necesario hacer que mi entidad sea serializable?

Respuesta

33

Esto sucede generalmente si mezcla HQL y consultas SQL nativas. En HQL, Hibernate mapea los tipos que pasa a cualquier cosa que el DB entienda. Cuando ejecuta SQL nativo, debe hacer el mapeo 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).

34

necesita que sus entidades sean Serializable si necesita transferirlos sobre el alambre (serializarlos a alguna otra representación), almacenarlos en sesión HTTP (que a su vez está serializado en el disco duro por el servlet contenedor), etc.

Solo por el bien de la persistencia, Serializable no es necesario, al menos con Hibernate. Pero es una buena práctica hacerlos Serializable.

+2

No sé, tal vez mis entidades están siendo transferidas implícitamente a alguna parte. Yo uso hibernate + spring + jsf y Tomcat. ¿Dónde en esta cadena puede tener lugar la transferencia? – Roman

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ás haciendo algo más con las entidades, que requieren que sean serializables.

92

Según JPA Spec:

Si una instancia de entidad ha de ser pasado por valor como un objeto individual (por ejemplo, a través de una interfaz remota), la clase de entidad debe implementar la interfaz Serializable.

"JSR 220: Enterprise JavaBeans, la versión 3.0 de Java Persistence API versión 3.0, Final Mayo 2, 2006"

+11

(+1) mirando la especificación siempre es fructífero – Bozho

+9

No veo por qué esto tiene tantos votos ascendentes. 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

+0

No estoy seguro de hibernar, pero con otros proveedores de JPA hay operaciones que requieren que el proveedor haga una copia de una entidad (objeto). 'Serializable' podría ser útil con eso, y en el contexto de persistencia más consistente que' Cloneable' por ejemplo. – JimmyB

4

Creo que su problema está relacionado con tener un campo de un tipo complejo (clase), que no está anotado En tales casos, el modo predeterminado va a almacenar el objeto en su forma serializada en la base de datos (que probablemente no es lo que pretende hacer) Ejemplo:

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

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

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

8

Para complementar la buena respuesta de Conor que se refirió a las especificaciones JSR-317. Normalmente, 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 los beans de su entidad se puedan serializar a medida 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: Beans that use session, application, or conversation scope must be serializable, but beans that use request scope do not have to be serializable. Por lo tanto, los beans de entidad JPA subyacentes -si los hubiera- seguirían la misma semántica.

1

De acuerdo con la hibernate docs, durante el uso de @JoinColumn anotación:

Ha uno más parámetros con nombre referencedColumnName. Este parámetro declara la columna en la entidad objetivo que se utilizará para la unión. Tenga en cuenta que cuando se usa referencedColumnName en una columna de clave no primaria, la clase asociada debe ser Serializable.

0

Este es también el error que se produce al pasar un ID incorrectamente tipeado como el segundo parámetro a algo como em.find() (es decir, pasar la propia entidad en lugar de su ID). No he encontrado todavía necesario declarar las entidades JPA serializables, no es realmente necesario a menos que esté usando referenciaColumnName como lo describe aman.

0

golpe remoto usando cartero o ajax o angular js etc ....., puede causar el ciclo de repetición con la excepción de StackOverflow con Jackson fasterxml.Así que es mejor usar el serializador.

Cuestiones relacionadas