-1

I have a class that needs to be serialized.

Example

public class Employee implements Serializable {
   Column column;
   public Column getColumn() {
       return column;
   }
}

When I try to serialize the employee object, I get the exception

java.io.NotSerializableException: net.sf.jsqlparser.schema.Column at java.io.ObjectOutputStream.writeObject0(Unknown Source)

I cannot make Column attribute as transient, because information is required. How do I solve this issue?

  • 1
    Implement [custom serialization](http://stackoverflow.com/a/7290812/2071828) or use some other method to persist the your object. N.B. Please stick to Java naming conventions, classes should be in `PascalCase`; so `Employee`. – Boris the Spider Apr 03 '14 at 07:25
  • What do you mean by "I cannot make Column attribute as transient". You should make it `Serializable` as well, if that's an option. – Drux Apr 03 '14 at 07:29
  • If you have Column class then make it serializable too. – Deepu--Java Apr 03 '14 at 07:29
  • @Deepak2221 : Column Class is present in some API, I cannot change – Palaniappan Meiyappan Apr 03 '14 at 07:30
  • @Drux, I don't want to make it transient. I want the information after de-serialization. How do I make it Serializable, that was my question? – Palaniappan Meiyappan Apr 03 '14 at 07:33
  • Related: [transient](http://stackoverflow.com/questions/910374/why-does-java-have-transient-variables). IMO you should mention in your question that you cannot change `Column` (as stated in a comment below). – Drux Apr 03 '14 at 08:01

5 Answers5

1

to implement custom serialization you must implement writeObject and readObject in Employee as below:

private void writeObject(ObjectOutputStream os) {
    // throws IOException {
   try {
    os.defaultWriteObject();
    os.writeInt( ... ); // here serialize column
   } catch (Exception e) { e.printStackTrace(); }
  }

  private void readObject(ObjectInputStream is) {
    // throws IOException, ClassNotFoundException {
   try {
    is.defaultReadObject();
    column = new Column( /*is.readInt() ... */); // here deserialize column
   } catch (Exception e) { e.printStackTrace(); }
  }

also you should mark your column field, that is of non Serializable type as transient:

transient Column column;

this way ObjectOutputStream will skip serializing it (no exception will be thrown), and you will serialize it in readObject.

marcinj
  • 48,511
  • 9
  • 79
  • 100
0

Column class should be implementing Serializable

Karthigeyan Vellasamy
  • 2,038
  • 6
  • 33
  • 50
0

If you need the information after unserialization, you must use custom serialization.

thobens
  • 1,729
  • 1
  • 15
  • 34
0

There is one solution of this. Make a custom class by extending Column and implement and make it Serializable.

class ColumnDup extends Column implements Serializable{}

and use ColumnDup in place of Column.

Deepu--Java
  • 3,742
  • 3
  • 19
  • 30
  • @PalaniappanMeiyappan this might be your solution. – Deepu--Java Apr 03 '14 at 07:42
  • 1
    this will not work, Column fields will be default initialized after deserialization – marcinj Apr 03 '14 at 07:46
  • @marcin_j can you explain this in deep. – Deepu--Java Apr 03 '14 at 07:47
  • This is because during deserialization of non-Serializable base classes, their constructors will get executed causing default initialization. Inside ObjectStreamClass.newInstance() you can read: `Creates a new instance of the represented class. If the class is externalizable, invokes its public no-arg constructor; otherwise, if the class is serializable, **invokes the no-arg constructor of the first non-serializable superclass.**` – marcinj Apr 03 '14 at 08:01
0

You can write custom serialization bu using

private void writeObject(ObjectOutputStream out)

private void readObject(ObjectInputStream in)

refer this useful link http://www.coderanch.com/t/504517/java/java/Customize-readObject-writeObject

Ashok_Pradhan
  • 1,159
  • 11
  • 13