JCMS 8.0.2 > Soucis lors de la mise à jour d'un MemberExtension

thomas lavocat · le 25/09/14 à 11:51

Bonjour,

J'ai un soucis lors de la mise à jour d'un MemberExtension, l'extension n'est pas mise à jour dans le store :

Voici mon code :

Category           categorieTags       = channel.getCategory(channel.getProperty("$id.categorie.tags"));
MemberExtension     extension          = (MemberExtension) loggedMember.getExtension();
TreeSet<Category>  categoriesChoisies  = extension.getAbonnementActualite();
String[]           idSelectionnes      = request.getParameterValues("categorieChoisie");

//Si aucuns id récupéré, aucune modification ne doit être faite dans le membre
if(Util.notEmpty(idSelectionnes)){
    //La liste des catégories est au préalable vidée pour être remplie avec
    //uniquement ce qui a été selectionné
    categoriesChoisies.clear();
    
    for(int i=0; i<idSelectionnes.length; i++){
        Category catSelectionnee = channel.getCategory(idSelectionnes[i]);
        if(Util.notEmpty(catSelectionnee))
            categoriesChoisies.add(catSelectionnee);
    }
    
    extension.setAbonnementActualite(categoriesChoisies);
    extension.performUpdate(Channel.getChannel().getDefaultAdmin());
}

 

Lorsque j'éxecute ce code, j'ai l'erreur suivante :

11:50:17,809 ERROR [DEV - Contact] [Channel] - Could not update Data generated.MemberExtension dni_5884 ([class: generated.MemberExtension] [id: dni_5884] [author: null] ).
com.jalios.jstore.NoUpdateException: Data to update is the same instance as the data already in memory!!
    at com.jalios.jstore.Store.update(Store.java:1079)
    at com.jalios.jcms.Channel.updateData(Channel.java:5615)
    at com.jalios.jcms.Data.performUpdate(Data.java:2743)
    at com.jalios.jcms.Data.performUpdate(Data.java:2724)
    at org.apache.jsp.plugins.CG59ITypes.types.PortletJSP.doGererMesAbonnements_jsp._jspService(doGererMesAbonnements_jsp.java:943)

Comment faire pour que ça fonctionne ?

#1

je précise, que l'objet en mémoire est bien mis à jour, puisque mon formulaire suit. Par contre au redémarrage je perds toutes les modifications

thomas lavocat · le 25/09/14 à 11:51
4 pts
Olivier Jaquemet · le 25/09/14 à 12:06

Bonjour Thomas,

Tout objet JCMS doit pour être mis à jour passer préalablement par une copie : 

MemberExtension extension = (MemberExtension) loggedMember.getExtension();
extension = (MemberExtension) extension.getUpdateInstance()

JCMS 101 :)

0 pt
thomas lavocat · le 25/09/14 à 12:21

Bonjour Olivier,

Merci pour la réponse. Par contre en mettant ce bout de code en place, je n'ai certes plus l'erreur, mais lorsque je redémarre mon serveur, les modifications n'ont pas été prises en compte.

 

Voici mon code mis à jour :

Category            categorieTags       = channel.getCategory(channel.getProperty("$id.categorie.tags"));
MemberExtension     extension           = (MemberExtension) loggedMember.getExtension();
TreeSet<Category>   categoriesChoisies  = extension.getAbonnementActualite();
String[]            idSelectionnes      = request.getParameterValues("categorieChoisie");

//Si aucuns id récupéré, aucune modification ne doit être faite dans le membre
if(Util.notEmpty(idSelectionnes)){
    //création de l'instance qui peut être mise à jour
    extension = (MemberExtension) extension.getUpdateInstance();
    //La liste des catégories est au préalable vidée pour être remplie avec
    //uniquement ce qui a été selectionné
    categoriesChoisies.clear();
    
    for(int i=0; i<idSelectionnes.length; i++){
        Category catSelectionnee = channel.getCategory(idSelectionnes[i]);
        if(Util.notEmpty(catSelectionnee))
            categoriesChoisies.add(catSelectionnee);
    }
    
    extension.setAbonnementActualite(categoriesChoisies);
    extension.performUpdate(Channel.getChannel().getDefaultAdmin());
}

 

Faut-il mettre à jour le membre aussi ?

Si oui, faut-il le cloner aussi ?

#3

Merci pour la documentation. Par contre est-ce que tu as des explications plus détaillées ? Je veux dire, à partir du moment où l'objet de type AbonnementActualite possède une référence vers un objet de type TreeSet, en modifiant le contenu directement via la référence l'objet de type AbonnementActualite devrait pouvoir accéder lui même aux modifications.

Du coup, comment ça se fait que ce ne soit pas le cas ? Parce-que c'est étonnant de devoir passer par la recopie et la duplication mémoire pour que la modification soit prise en compte. Est-ce parce-que ça se base sur un ID pour savoir si quelque chose à changé ?

thomas lavocat · le 25/09/14 à 13:06
#4

L'explication est simplissime, c'est lié au fonctionnement de JStore :

  • JStore est une base de donnée journalisé qui n'enregistre que les changement d'une donnée par rapport à son état précédent
  • qui dit détection de changement dit état avant (la donnée d'origine) et état apres (le clone en cours de modif)
  • si dans le clone en cours de modif tu ne clone pas le categoryset, alors quand tu le modifie ça modifie l'original
    donc lors du performUpdate JStore compare le avant/apres : pas de changement détecté == pas d'enregistrement sur disque
Olivier Jaquemet · le 25/09/14 à 14:38
#5

Je note, merci pour la précision ;-)

thomas lavocat · le 30/09/14 à 09:36
0 pt