When and why JPA entities should implement the Serializable interface?

Viewed 112858

The question is in the title. Below I just described some of my thoughts and findings.

When I had a very simple domain model (3 tables without any relations), all my entities did NOT implement the Serializable interface.

But when the domain model became more complex, I got a RuntimeException, saying that one of my entities didn't implement Serializable.

I use Hibernate as a JPA implementation, and I wonder:

  1. Is it a vendor-specific requirement/behavior?
  2. What happens with my serializable entities? Should they be serializable for storing or for transferring?
  3. At which moment it becomes necessary to make my entity serializable?
14 Answers

According to JPA Spec:

If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface.

"JSR 220: Enterprise JavaBeansTM,Version 3.0 Java Persistence API Version 3.0, Final Release May 2, 2006"

You need your entities to be Serializable if you need to transfer them over-the-wire (serialize them to some other representation), store them in http session (which is in turn serialized to hard disk by the servlet container), etc.

Just for the sake of persistence, Serializable is not needed, at least with Hibernate. But it is a best practice to make them Serializable.

This usually happens if you mix HQL and native SQL queries. In HQL, Hibernate maps the types you pass in to whatever the DB understands. When you run native SQL, then you must do the mapping yourself. If you don't, then the default mapping is to serialize the parameter and send it to the database (in the hope that it does understand it).

JPA specification

According to the JPA specification, an entity should implement Serializable only if it needs to be passed from one JVM to another or if the entity is used by a Stateful Session Bean which needs to be passivated by the EJB container.

If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface.

Hibernate

Hibernate only requires that entity attributes are Serializable, but not the entity itself.

However, implementing the JPA specification, all the JPA requirements regarding Serializable entities apply to Hibernate as well.

Tomcat

According to Tomcat documentation, the HttpSession attributes also need to be Serializable:

Whenever Apache Tomcat is shut down normally and restarted, or when an application reload is triggered, the standard Manager implementation will attempt to serialize all currently active sessions to a disk file located via the pathname attribute. All such saved sessions will then be deserialized and activated (assuming they have not expired in the mean time) when the application reload is completed.

In order to successfully restore the state of session attributes, all such attributes MUST implement the java.io.Serializable interface.

So, if the entity is stored in the HttpSession, it should implement Serializable.

If we just talk about persistence, Serializable is not needed But it is best practice to make the entities Serializable.

If we are exposing domain/entities objects directly exposed to the presentation layer, instead of using DTO , In that case we need to implement Serializable. These domain objects can be stored in HTTPSession for caching/optimization purposes. A http-session can be serialized or clustered. And it is also required for transferring data between JVM-instances.

When we use DTO to decouple persistence layer and service layer, marking the domain objects as Serializable would be counter productive and would violate the “encapsulation”. Then it becomes an anti-pattern.

Composite identifiers

The primary key class must be serializable.

POJO Models

If an entity instance is to be used remotely as a detached object, the entity class must implement the Serializable interface.

Cache
In addition, if you are implementing a clustered second level cache then your entities must be serializable. The identifier has to be Serializable because that’s a JPA requirement since the identifier might be use as the key for a second-level cache entry.

And when we serialize entities make sure to provide explicit serialVersionUID with private access modifier. Because if a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in Java(TM) Object Serialization Specification . Default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization.

Classes must implement Serializable if you want to serialize them. This is not directly related to JPA and the JPA specification does not require that entities are serializable. If Hibernate really complains about this, I suppose it is a Hibernate bug, but I suppose that you directly or indirectly are doing something else with the entities, which require them to be serializable.

Please refer http://www.adam-bien.com/roller/abien/entry/do_jpa_entities_have_to it says, The implementation of java.io.Serializable is simply required for transfering data via IIOP or JRMP (RMI) between JVM-instances. In case of a pure web application the domain objects are sometimes stored in HTTPSession for caching / optimization purposes. A http-session can be serialized (passivation) or clustered. In both cases all the content have to be Serializable.

  1. At which moment it becomes necessary to make my entity serializable?

Implementing ehcache with diskstore as second level cache (i.e. using @Cacheable annotation on entity or repository/service method) requires Serializable, otherwise the cache will fail (NotSerializableException) to write the entity to the disk cache.

remote hit using postman or ajax or angular js etc....., may cause the repeat cycle with StackOverflow exception with Jackson fasterxml.So, it is better to use serializer.

when JPA entities are used as parameters or return values by the remote EJB operations

Related