2

I am trying to store my object in MySQL database using java language. I am trying to convert object into byte so I can store it into LONGBLOB. But I am facing error i.e "NotSerializable Exception".

My Class whose object I want to sore:

public class Books implements Serializable {

private int isbn;
private String bookName;
private String author;
private String edition;
private int rowNo;
private int colNo;
private String shelfNo;
private String img;
private InputStream imag;
validation v = new Validation();
Database database;

public Books() { database = new Database(); }
.
.
setters & getters...

Method to call database method to insert object in database:

String className = this.getClass().getName();
database.insertBookRecord(this.getIsbn(), this, className);  

this is the object of current class which I want to store.

following is the insertBookRecord method.

    public void insertBookRecord(int isbn, Books book, String name) {
    String query = "INSERT INTO Test VALUES (?, ?, ?)";
    byte[] data = null;
    //book = new Books();
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(book);
        oos.flush();
        oos.close();
        baos.close();
        data = baos.toByteArray();
    }
    catch(IOException ex) {
        JOptionPane.showMessageDialog(null, ex.getMessage());
    }

    try {

        //conn.setAutoCommit(false);
        state = conn.prepareStatement(query);
        state.setInt(1, isbn);
        state.setString(2, name);
        state.setObject(3, data);
        state.executeUpdate();
        //conn.commit();
    }
    catch(SQLException ex) {
        JOptionPane.showMessageDialog(null, ex.getMessage());
    }
    finally {
        close(3);
    }
}

When I reach at statement oos.writeObject(book); Its stops with exception and displays the the package & Classname in the JOptionPane.

My book object has all the data fields I entered in the text fields. But I am unable to write it./convert it into Serializable format.

Any suggestions please?

Stack Trace:

java.io.NotSerializableException: com.my.classes.Database
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at com.my.classes.Database.insertBookRecord(Database.java:123)
at com.my.classes.Books.insertBookRecord(Books.java:107)
at com.my.jlms.ManageBooks$2.actionPerformed(ManageBooks.java:308)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
nix
  • 165
  • 2
  • 4
  • 19
  • We would need to see the `fields` in your `Books` class. Or better yet something in there is not `Serializable` – 3kings Mar 30 '16 at 13:53
  • Probably one or more of the fields inside your Book class is not serializable. Where's your stacktrace? – f1sh Mar 30 '16 at 13:54
  • I have updated the fields. – nix Mar 30 '16 at 13:56
  • 5
    You have to declare the input stream as `transient`. – Ralf Mar 30 '16 at 13:57
  • @nix Well there you see it... `InputStream` does not implement Serializable – 3kings Mar 30 '16 at 13:57
  • @Ralf @3kings aha.. But I am also saving an image in the object so thats why I used InputStream to convert image into that. or do I need not use InputSream, and `writeobject` will do this for the path to my image itself? – nix Mar 30 '16 at 14:02
  • A stream is not a container to store things. It is used to move data between endpoints. E.g. from an image file to a byte array in your application. Also, if you do not close the input stream after you are done with it, you create a resource leak. – Ralf Mar 30 '16 at 14:06
  • I see, I have commented out InputStream, but still facing the same issue. stacktrace: http://pastebin.com/YwQf0izy – nix Mar 30 '16 at 14:16
  • I figured out the problem, its not serializing an object inside the other object. I mean if you see the code, I have declared constructor so its not serializing the database object, similarly its not serializing the validation object. If I remove them and put inside method, it works fine i.e serialization done. But I do want them in the field and constructor so I don't have declare them again and again. Is it possible to not let that serialize? – nix Mar 30 '16 at 21:36
  • Declare them as transient. – Ralf Mar 31 '16 at 06:27

3 Answers3

1

You get the exception because you are trying to serialize an InputStream

private InputStream imag;

InputStream is not Serializable

You could omit this field when serializing by declaring it transient:

private transient InputStream imag;
Diyarbakir
  • 1,999
  • 18
  • 36
0

Your imag is InputStream which is not implement Serializable. It should be a byte[] or String link to your imag location.

Edited: You should separate business from model object. Move insertBook method and database object from Book class to another class.

An Do
  • 309
  • 1
  • 8
  • I tried it, even removed InputStream, but still the same error. you ca view the stacktrace error http://pastebin.com/YwQf0izy – nix Mar 30 '16 at 14:14
  • I see the problem. I don't know why you need database object in your book but please move your logic to another class `String className = this.getClass().getName(); database.insertBookRecord(this.getIsbn(), this, className); ` – An Do Mar 30 '16 at 14:21
  • I figured out the problem, its not serializing an object inside the other object. I mean if you see the code, I have declared constructor so its not serializing the database object, similarly its not serializing the validation object. If I remove them and put inside method, it works fine i.e serialization done. But I do want them in the field and constructor so I don't have declare them again and again. Is it possible to not let that serialize? – nix Mar 30 '16 at 21:36
0

So the problem was InputStream as well as i was trying to Seralize the objects i.e V & database. I just added transient e.g private transient Database database; and then declared database = new Database(); in the constructor. hence I was able to serialize it.

Thank you @Ralf, @Joseph, @Diyarbakir and @3kings for helping me out.

nix
  • 165
  • 2
  • 4
  • 19