lundi 20 avril 2015

Spring unwillingly changes values in my Bean

I named the subject as clear as I could but if it's not, here's the detail, should be long, but my problem, is really weird.

I hope my explanations won't get you confused. Thanks in advance for you help!

EDIT : as there aren't many answers/questions, perhaps my explanations are confusing/unpleasant to read. So, here's a resume : between two methods, I can observe a change in the value of a property of an object, getting the object in a wrong state. Details below :)

I have a Spring/JSF webapp which, among other things, manages a user database. When you load the management page, it displays the data in a p:dataTable (PrimeFaces).

The problem is : when I select a row in the dataTable, it calls the corresponding listener which sets a temporary object in my backingBean. By now, all the properties values correspond to the row selected.

But, when I call a method by clicking a button, and try to retrieve my object in the backing bean, it returns me the correct object (memory address is the same) with all the properties right, except one (see below).

Precisely, when i call my Listener (listenerselectadmin), the value superAdministrateur of the selection is True. Then, when I call the method Test(), the value of superAdministrateur is false, but all the other values aren't changed (see below).

I toggled a breakpoint in the setter of superAdministrateur and it's called several times, the first one with the right value (true), the next ones with the wrong one (false)...

There's no method created by me between these two, so I deduced that Spring modified the value, but why?

To prove it, I created another object : admintemp. In the listener I stock my selection in the object adminSelectionne in the backingBean. Naturally, Spring gives adminSelectionne the memory address of the selection, so it doesn't have to create a new object. Then, I set property by property the values of the selection in the new object adminTemp. When I do so, Spring allocates the same memory address to this object and I have the bug generated to both adminTemp and adminSelectionne.

However, if I set all properties of adminTemp with the values of the selection but one, when I try to retrieve the object in the method test, it has been destroyed (null)...

EDIT : the method getAdministrateurModel() retrieve the model of my MVC in the conversation. NOT part of the problem, I invastigated on the question by retrieving the model with other techniques. Plus, I retrieve my objects with the same memory adress, so the Model is the right one.

Here is my object class :

@Entity
public class Administrateur implements Serializable{

private static final long serialVersionUID = 1L;

//Attributs
private int idAdministrateur;
private String numeroCP;
private boolean superAdministrateur=true;
private String superAdministrateurAnalog;
private Gerant gerant;

//Getters / Setters
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
public int getIdAdministrateur() {
    return idAdministrateur;
}
public void setIdAdministrateur(int idAdministrateur) {
    this.idAdministrateur = idAdministrateur;
}

@Column(unique=true)
public String getNumeroCP() {
    return numeroCP;
}
public void setNumeroCP(String numeroCP) {
    this.numeroCP = numeroCP;
}

public boolean isSuperAdministrateur() {
    return superAdministrateur;
}
public void setSuperAdministrateur(boolean superAdministrateur) {
    this.superAdministrateur = superAdministrateur;
    if(superAdministrateur){
    this.superAdministrateurAnalog = "Oui";
    }else{
    this.superAdministrateurAnalog = "Non";
    }
}

@ManyToOne @JoinColumn(name="gerant_id")
public Gerant getGerant() {
    return gerant;
}
public void setGerant(Gerant gerant) {
    this.gerant = gerant;
}

public String getSuperAdministrateurAnalog() {
    return superAdministrateurAnalog;
}
public void setSuperAdministrateurAnalog(String superAdministrateurAnalog) {
    this.superAdministrateurAnalog = superAdministrateurAnalog;
}
//Constructors
public Administrateur(){

}

public Administrateur(int id, String numCP, boolean sa){
    this.idAdministrateur=id;
    this.numeroCP=numCP;
    this.superAdministrateur=sa;
}
}

Here is my Backing Bean (resumed to the code needed):

@Component
public class AdministrateurModel implements Serializable{

    /**
 * 
 */
private static final long serialVersionUID = 1L;

//Attributes

private Administrateur adminselectionne = new Administrateur();

private Administrateur admintemp = new Administrateur();

    //Getters / Setters


public Administrateur getAdminselectionne() {
    return adminselectionne;
}

public void setAdminselectionne(Administrateur adminselectionne) {
    this.adminselectionne = adminselectionne;
}

public Administrateur getAdmintemp() {
    return admintemp;
}

public void setAdmintemp(Administrateur admintemp) {
    this.admintemp = admintemp;
}
}

Here the method of Controller that are used for this problem:

@Controller("administrateurController")
@Scope("session")
public class AdministrateurController{

public void listenerselectadmin(SelectEvent selectEvent){
    AdministrateurModel model = getAdministrateurModel();
    Administrateur selection = (Administrateur) selectEvent.getObject();
    model.setAdminselectionne(selection);

    model.setAdmintemp(new Administrateur());
    model.getAdmintemp().setGerant(selection.getGerant());
    model.getAdmintemp().setNumeroCP("Test");
    model.getAdmintemp().setSuperAdministrateur(selection.isSuperAdministrateur());
    model.getAdmintemp().setSuperAdministrateurAnalog(selection.getSuperAdministrateurAnalog());


//flag in the model, which enable/disable buttons rendering on the JSF page
    model.setDisabledAdmin(false);
}

public void test(){
    AdministrateurModel model = getAdministrateurModel();
    System.out.println(model.getAdminselectionne());
    System.out.println(model.getAdminselectionne().getNumeroCP());
    System.out.println(model.getAdminselectionne().getSuperAdministrateurAnalog());
    System.out.println(model.getAdminselectionne().isSuperAdministrateur());

    System.out.println(model.getAdmintemp());
    System.out.println(model.getAdmintemp().getNumeroCP());
    System.out.println(model.getAdmintemp().getSuperAdministrateurAnalog());
    System.out.println(model.getAdmintemp().isSuperAdministrateur());
}

Aucun commentaire:

Enregistrer un commentaire