IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Persistance des données Java Discussion :

A quoi servent les Callbacks et les Entity Listeners ?


Sujet :

Persistance des données Java

  1. #1
    Membre éclairé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 200
    Points : 792
    Points
    792
    Par défaut A quoi servent les Callbacks et les Entity Listeners ?
    Bonjour à tous,
    Après avoir brièvement lu sur les Callbacks et les Entity Listeners, je pensais pouvoir auditer les opérations de manipulation de données (CRUD) de mon système. Mais au moment de me jeter à l’eau, je me rends compte qu’il n’est pas conseillé d’exécuter les méthodes du gestionnaire d’entité ou de l’objet Query dans ces méthodes (Bref, la spécification ne supporte pas cela) . Fort de ce constat, je me demande à quoi servent vraiment les callback et les entity listener ? Y-a-t ’il quelqu’un pour m’aider à voir clair ? Merci et bonne continuation à tous.
    Ingénieur Recherche et Développement en informatique à Sopra

    Page perso developpez : http://armel-ndjobo.developpez.com/
    Suivez moi sur twitter : ndjobo

  2. #2
    Membre éprouvé

    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2005
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Juin 2005
    Messages : 588
    Points : 1 230
    Points
    1 230
    Par défaut
    Effectivement... l'utilisation (et, l'utilité) des listeners dans JPA est assez limité puisque tu ne peux pas travailler avec l'entity manager

    En se creusant la tête:
    - auditing de tes entités
    ou encore, le déclenchement d'évènements
    - gestion des évènements CDI (mais, avec l'impossibilité d'injecter directement un bean CDI),
    - gestion des messages via JMS,
    - ...

    a+
    Philippe

  3. #3
    Membre confirmé Avatar de ruscov
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2007
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2007
    Messages : 347
    Points : 500
    Points
    500
    Par défaut
    Personnellement j'utilise les listeners pour mettre automatiquement à jour certains champs de mes entity (lastmodified par exemple). Tu peux voir ça comme un trigger.
    Mes logiciels n’ont jamais de bug. Ils développent juste certaines fonctions aléatoires.

  4. #4
    Membre éclairé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 200
    Points : 792
    Points
    792
    Par défaut
    Là encore il y a une limitation. Il n'est pas possible de modifier les attributs relationnels de l'entité.
    Ingénieur Recherche et Développement en informatique à Sopra

    Page perso developpez : http://armel-ndjobo.developpez.com/
    Suivez moi sur twitter : ndjobo

  5. #5
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Points : 3 938
    Points
    3 938
    Par défaut
    Citation Envoyé par naf87 Voir le message
    Là encore il y a une limitation. Il n'est pas possible de modifier les attributs relationnels de l'entité.
    Bonjour, peux tu développer ça? Les CallBack comme dit dans le précédent post doivent être considérés comme des triggers agissant sur tous les champs d'une entité (changement de valeur) avant sa persistence.Ils ont toute leur utilité pour garantir une certaine cohérence de la base de donnée avant toute transaction.Personnellement je n'ai pas encore eu besoin d'invoquer un em dans un Listener.Toutefois l'inconvenient que je peux trouver à ce mécanisme c'est un risque d'oubli lors d'une maintenance applicative (évolution, non report de correction de bug), le même inconvenient que je trouve aux mécanismes trigger.
    Vous avez peut être hâte de réussir et il n'y a rien de mal à cela...
    mais la patience est aussi une vertu; l'échec vous l'enseignera certainement..."

  6. #6
    Membre éclairé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 200
    Points : 792
    Points
    792
    Par défaut
    Là encore il y a une limitation. Il n'est pas possible de modifier les attributs relationnels de l'entité.
    les attributs relationnels sont les attributs qui représente un ou plusieurs objet(s) d'une autre entité. Bref, le type de l'attribut est une Collection d'entité ou une entité. Et d'après la spécification (Si mon anglais est encore bon ), ce type d'attribut ne devrait pas être modifié dans les callbacks.

    Et comme je l'ai dit dans mon tout premier post, je m'imaginais pouvoir renseigner ma table d'audit grâce aux callbacks. Étant donné qu'il y a des méthodes qui peuvent être exécutées avant et après la mise à jour, l'enregistrement et la suppression des données.

    Ils ont toute leur utilité pour garantir une certaine cohérence de la base de donnée avant toute transaction
    Si le mot cohérence ici fait uniquement allusion à la validation des données, je dirais qu'il y a un mécanisme de validation définit par la jsr 303, que je trouve assez intéressant.
    Ingénieur Recherche et Développement en informatique à Sopra

    Page perso developpez : http://armel-ndjobo.developpez.com/
    Suivez moi sur twitter : ndjobo

  7. #7
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Points : 3 938
    Points
    3 938
    Par défaut
    Citation Envoyé par naf87 Voir le message
    les attributs relationnels sont les attributs qui représente un ou plusieurs objet(s) d'une autre entité. Bref, le type de l'attribut est une Collection d'entité ou une entité. Et d'après la spécification (Si mon anglais est encore bon ), ce type d'attribut ne devrait pas être modifié dans les callbacks.
    C'est mal connaitre les listeners,pourquoi as tu besoin à partir d'un listener d'une entité en modifier une autre, si sur chaque entité tu peux définir un listener spécifique, qui va être automatiquement appelé derrière une propagation de modification par exemple.Encore une fois je ne vois pas trop l'interet d'un em dans les listener.
    Vous avez peut être hâte de réussir et il n'y a rien de mal à cela...
    mais la patience est aussi une vertu; l'échec vous l'enseignera certainement..."

  8. #8
    Membre confirmé Avatar de ruscov
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2007
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2007
    Messages : 347
    Points : 500
    Points
    500
    Par défaut
    Tu peux développer un peu plus ce que tu veux faire, peut-être qu'on pourra t'apporter une solution.
    En fait je pense à Hibernate Envers qui permet de faire des audits.
    Mes logiciels n’ont jamais de bug. Ils développent juste certaines fonctions aléatoires.

  9. #9
    Membre éclairé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 200
    Points : 792
    Points
    792
    Par défaut
    Voici en substance ce que je voulais faire :

    Exemple d'entité à auditer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    @Entity
    @EntityListeners(AuditEntityListener.class)
    public class Produit extends Auditable implements Serializable {
        @Id
        private String numProd;
        private Integer pu;
        @Temporal(TemporalType.TIMESTAMP)
        private Date datecre;
     
     
        public Produit() {
     
        }
     
        @PrePersist
        @PreUpdate
        @PreRemove
        public void initValues(){
            entityName = "Produit";
            entityId = numProd;
        }
     
        public String getNumProd() {
            return numProd;
        }
     
        public void setNumProd(String numProd) {
            detailsAudit.put("numProd", new AuditValue(numProd, this.numProd));
            this.numProd = numProd;        
        }
     
        public Integer getPu() {
            return pu;
        }
     
        public void setPu(Integer pu) {
            detailsAudit.put("pu", new AuditValue(""+pu, ""+this.pu));
            this.pu = pu;
        }
     
        public Date getDatecre() {
            return datecre;
        }
     
        public void setDatecre(Date datecre) {
            detailsAudit.put("datecre", new AuditValue(""+datecre, ""+this.datecre));
            this.datecre = datecre;
        }
     
        //...
     
    }

    Le listener :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    public class AuditEntityListener {
        private EntityManager entityManager;
     
       public AuditEntityListener(){
           // lookup de l'entity manager déclaré dans un EJB
       }
     
        @PostUpdate
        public void auditUpdate(Auditable auditable){
            auditOperation(auditable, "UPDATE");
        }
     
        @PostRemove
        public void auditRemove(Auditable auditable){
            auditOperation(auditable, "REMOVE");
        }
     
        @PostPersist   
        public void auditPersist(Auditable auditable){
            auditOperation(auditable, "PERSIST");
        }
     
        private void auditOperation(Auditable auditable, String operation){        
            Audit audit = new Audit();
            ObjectUtils.copyProperties(audit,auditable);
            audit.setDateoperation(new Date());
            audit.setOperation(operation);
     
            entityManager.persist(audit);    
     
            //sauvegarde du détail
            for(String attribute : auditable.getDetailsAudit().keySet()){
                AuditValue value = auditable.getDetailsAudit().get(attribute);
                Detailsaudit detail = new Detailsaudit();
                detail.setFieldname(attribute);
                detail.setAudiId(audit.getId());
                detail.setNewlvalue(value.getNewValue());
                detail.setOdlvalue(value.getOldValue());
                entityManager.persist(detail);
            }
        }
    }
    l'entité Audit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Entity
    public class Audit  implements Serializable {
        @Id
        @GeneratedValue(strategy= GenerationType.SEQUENCE)
        private int id;
        private String userid;
        private String operation;  
        @Temporal(TemporalType.TIMESTAMP)
        private Date dateoperation;
        private String entityname;
        private String entityid;
     
       // getter et setter    
    }
    La classe Auditable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    public class Auditable {
        protected String entityName;
        @Enumerated(EnumType.STRING)
        protected OperationType operation;
        protected String userId;
        protected Date dateoperation;
        protected String entityId;
        protected Map<String,AuditValue> detailsAudit;
     
        {
            detailsAudit = new HashMap<String, AuditValue>();
        }
     
      // getter et setter      
    }
    la classe AuditValue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class AuditValue {
        private String newValue;
        private String oldValue;
     
        public AuditValue(){}
     
        public AuditValue(String newValue, String oldValue){
            this.newValue = newValue;
            this.oldValue = oldValue;
        }
       //getter et setter
    }
    et l'entité Detailsaudit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Entity
    public class Detailsaudit implements Serializable {
        @Id
        private int id;
        private int audiId;
        private String fieldname;
        @Column(length=1000)
        private String odlvalue;
        @Column(length=1000)
        private String newlvalue;
     
        //getter et setter 
    }
    Ingénieur Recherche et Développement en informatique à Sopra

    Page perso developpez : http://armel-ndjobo.developpez.com/
    Suivez moi sur twitter : ndjobo

  10. #10
    Membre éprouvé

    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2005
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Juin 2005
    Messages : 588
    Points : 1 230
    Points
    1 230
    Par défaut
    Il y a surement une raison pour laquelle tu souhaites séparer ton audit... Moi perso, je mets tout celà dans une @MappedSuperclass avec toutes les méthodes qui vont bien pour l'audit...
    Néanmoins, si tu veux continuer dans ce sens, IMHO, il faudrait auditer les méthodes de ta DAO via AOP et non pas tes entités directement... Après, tout dépend du framework que tu utilises par ailleurs !

    Si tu utilises Hibernate... comme te l'a indiqué Ruscov Hibernate Envers est une autre soluce pour l'audit...

    a+
    Philippe

  11. #11
    Membre confirmé Avatar de ruscov
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2007
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2007
    Messages : 347
    Points : 500
    Points
    500
    Par défaut
    Tu as regardé Hibernate Envers? C'est typiquement ce que tu as besoin.
    Mes logiciels n’ont jamais de bug. Ils développent juste certaines fonctions aléatoires.

  12. #12
    Membre éclairé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 200
    Points : 792
    Points
    792
    Par défaut
    Merci pour les réponse. Dès que je finis de regarder Hibernate Envers, je vous fait parvenir un mini compte rendu.
    Ingénieur Recherche et Développement en informatique à Sopra

    Page perso developpez : http://armel-ndjobo.developpez.com/
    Suivez moi sur twitter : ndjobo

Discussions similaires

  1. Réponses: 4
    Dernier message: 11/09/2006, 16h55
  2. Les callback et les classes
    Par koala01 dans le forum C++
    Réponses: 9
    Dernier message: 28/08/2006, 16h02
  3. Les polices dans les tables et les requêts
    Par zooffy dans le forum Access
    Réponses: 3
    Dernier message: 21/06/2006, 11h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo