3

I am developing Spring-mvc application.

I am getting NotSerializableException.

The exception is coming on the restart of the server. I search for the solution and got to know that session scoped beans should be serialized.

My session scoped bean implements serializable, but it gives exception for injected beans and services.

It asks me to serialize all injected beans and services.

I have serialized my beans but is it required to serialize services also.

Is it accepted behavior to serialize services also? If yes then will I have to serialize all the services in my applications?

Thanks.

Naman Gala
  • 4,670
  • 1
  • 21
  • 55

2 Answers2

5

Tomcat does serialize session scope bean whenever you restart or shutdown it and restore the session while starting. You can implement serializable for beans which you want to be restored. otherwise skip this error.

Edit: Making a class serializable means that class must not contain non-serializable references or those references must be declared transient.

While deserializing the object, transient fields will reset to default value, so you might need to reinitialize it using if( transientField == null) { .. }

Mahendra
  • 323
  • 1
  • 7
  • As mentioned in comments, making reference as transient results in NPE. I am just checking if I can solve this problem. My last option is to avoid it. – Naman Gala Jan 06 '15 at 08:00
  • 3
    @Mathendra might be good to extend the answer with instructions that the transient variables need to be re-set on session load. (usually: if (... == null) { ... } . though personally I reckon no session state bean should contain references to external services, ever, but it looks like the person asking the question has this. – Joeblade Jan 06 '15 at 08:32
  • @Joeblade, your point answered my question. I will removed the reference to external service, it is possible in my case. Though, in case of using reference to external service, I will have to use if (... == null) { ... } in every method of session bean where I am using external services. Can you please add this into answer, so that I can accept it. Thanks. – Naman Gala Jan 06 '15 at 09:01
  • @Joeblade That's implicit, but anyways thanks for pointing it out that lead to resolution. :) – Mahendra Jan 06 '15 at 09:11
  • @NamanGala Sorry didn't mean to steal your answer I really did mean for you to extend the answer. I'll add a second answer then if you don't want to write it up – Joeblade Jan 06 '15 at 10:05
3

As Mahendra already pointed out:

While deserializing the object, transient fields will reset to default value, so you might need to reinitialize it using if( transientField == null) { .. }

When you make a serializable bean, make sure that any reference you don't want to store to disk is marked as transient. This means that after the bean is loaded you re-set the members of the bean that were set as null.

for instance:

private transient SomeService localServiceRef;
SomeService getSomeService() {
    if (localServiceRef == null) {
        localServiceRef = SomeService.getInstance();
    }
    return localServiceRef;
}

Or you can store the id locally, and have a transient resolved object

private String objectId;
private transient SomeObject localObject;
SomeObject getLocalObject() {
    if (localObject == null) {
        localObject = SomeObjectFactory.getById(objectId);
    }
    return localObject;
}

Though this ofcourse depends on your actual code.

Personally I don't like working with beans that actually contain services and suchlike. I prefer having beans as value objects and services to be findable through other means.

Joeblade
  • 1,735
  • 14
  • 22