Class not serializable

1

Next, I'm studying a project involving javaWeb, with jsf + primefaces . I'm using apache tomcat 7 . The problem is happening when starting the apache service and then testing my application, in which the error I identified was as follows:

fev 25, 2016 2:42:56 PM org.apache.catalina.session.StandardSession writeObject
ADVERTÊNCIA: Cannot serialize session attribute contatoController for
session 707B3CF6A468012EFA4220B84449EB6B java.io.NotSerializableException: Bean.ContatoBean

My ContactBean class is as follows:

public class ContatoBean implements Serializable{
    private int id;
    private String nome;
    private String endereco;
    private String cidade;
    private String uf;
    private String telefone;
    private String celular;
    private String email;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public String getCidade() {
        return cidade;
    }

    public void setCidade(String cidade) {
        this.cidade = cidade;
    }

    public String getUf() {
        return uf;
    }

    public void setUf(String uf) {
        this.uf = uf;
    }

    public String getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    public String getCelular() {
        return celular;
    }

    public void setCelular(String celular) {
        this.celular = celular;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

Even though I remove implements serializable , it still gives error, does anyone know what it could be?

    
asked by anonymous 25.02.2016 / 19:01

2 answers

1

When an object is serialized in Java, this byte sequence, in addition to containing its nontransient instance attributes, carries a number that identifies the "version" of the class that was used during the process.

This is called serialVersionUID , that is, the serialization version identifier of a class.

This number is used to know if the object we are retrieving is a version "compatible" with the version of the class that was used when we serialized the object: in other words, .class files need not be the same for the serialization process to succeed.

Example:

public class ContatoBean implements Serializable{
 private static final long serialVersionUID = -1931519544424229043L;

// seu código..
}
    
25.02.2016 / 19:30
1

The class name to be entered as Bean.ContatoBean suggests that it is an inner class , that is, ContatoBean is declared inside Bean .

I also assume that the outer class has an attribute of type ContatoController .

For example:

public class Bean {
    ContatoController  contatoController;
    ...
    public class ContatoBean {
        ...
    }
}

The problem of inner classes is that they maintain an implicit reference to the outermost class, so that you can access their attributes. The side effect of this, in your case, is that Java is trying to serialize the outer class along with the inner class, because of the implicit reference.

There are two ways to work around this:

1. Static internal class

Simply change the inner class to be static. This causes it to not be able to access the attributes of the outer class, but at least you will get the desired result.

From there it will be a class like any other, accessible by other classes without having to have an instance of the outer class.

Example:

public class Bean {
    ContatoController  contatoController;
    ...
    public static class ContatoBean {
        ...
    }
}

2. Outsource the inner class

Move the inner class to a normal class, in a separate file.

I recommend this approach when working with frameworks like JSF or Spring, which instantiate classes using reflection.

Although they work with built-in classes most of the time, there are always some cases where it does not work well, like the one you came across.

This is because built-in classes work a bit differently from a normal class. Some of the details you've already noticed by what I wrote, such as the internal reference and also the class name contain the name of the external class.

    
28.02.2016 / 23:52