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

Hibernate Java Discussion :

Récupérer le nom des attributs ayant changé lors d'un update


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut Récupérer le nom des attributs ayant changé lors d'un update
    Bonjour, dans mon application j'envoie un automatiquement un mail lorsque qu'une mise à jour est faite.
    Je voudrais préciser ds ce meme mail les champs ayant été modifiés.

    Pour cela, jai cloné mon POJO avant de récuperer les valeurs des INPUTTEXT.
    J'ai donc mes 2 objects dont je voudrais récuperer le nom des attributs qui ne sont pas égaux...

    Il y a t-il un moyen simple de réaliser cette fonction???
    La méthode equals() permettant seulement de renvoyer un boolean sur l'égalité...

    Merci

  2. #2
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 890
    Par défaut
    Hmm..

    J'avoue que ce n'est pas d'une simplicité exemplaire, mais je peux te proposer quelque chose..

    Si tu as spring, il faut que tu injectes ton SessionFactory avec un EntityInterceptor. Si tu n'as pas spring il faut que tu utilises le setter de ta session factory pour le faire.

    Dans Spring :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
     
    		 <property name="entityInterceptor" ref="findDirtyFields" />
    .... Le reste de la déclaration de ta sessionFactory
    Sans spring : la même chose

    Ton entityInterceptor ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public class FindDirtyFields extends EmptyInterceptor {
    ...
    Et il possède une méthode comme celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    	public int[] findDirty(Object entity,
                Serializable id,
                Object[] currentState,
                Object[] previousState,
                String[] propertyNames,
                Type[] types){
    ...
    Sur chacun de tes types, tu as la méthode "isDirty" pour repérer le changement... Je te conseille de débuguer cette méthode dans ton debuggeur, et de voir ce qu'elle te retourne, tu devrais comprendre assez facilement ce que contiennent les différents objets qui sont obtenus en paramètre de la méthode findDirty..

    A+

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Merci bcp je vais essayer tout ca

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 71
    Par défaut
    Pourquoi pas une méthode de ce style:

    public List<String> compareTo(Object o){[...]}

    Elle pourrait te retourner la liste des attributs différents entre o et this...

  5. #5
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 890
    Par défaut
    Citation Envoyé par Sensei.f Voir le message
    Pourquoi pas une méthode de ce style:

    public List<String> compareTo(Object o){[...]}

    Elle pourrait te retourner la liste des attributs différents entre o et this...
    Si ton objet à sauvegardé est déjà dans ta session, tu ne pourras pas avoir deux objets avec le même id en mémoire car hibernate garantie que le cas ne se produira pas..

    Et pourquoi réinventer ce qui existe déjà ? ( ta méthode serait un peu compliqué avec de la reflexivité et je te raconte pas pour les collections )

    A+

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 71
    Par défaut
    Citation Envoyé par KiLVaiDeN Voir le message
    Si ton objet à sauvegardé est déjà dans ta session, tu ne pourras pas avoir deux objets avec le même id en mémoire car hibernate garantie que le cas ne se produira pas..
    Il suffirait de créer un nouvel objet à partir de l'id de celui en session:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    objAvantMAJ = em.find(objSession.getId());
    ...
    Sauvegarde de objSession
    ...
     
    List<String> listeDesAttributModifié = objAvantMAJ.compareTo(objSession);
    Citation Envoyé par KiLVaiDeN Voir le message
    Et pourquoi réinventer ce qui existe déjà ? ( ta méthode serait un peu compliqué avec de la reflexivité et je te raconte pas pour les collections )

    A+
    Certes, en faisant une méthodes générique, ça va pas être évident...
    Mais s'il en a besoin que dans une seule classe, il peut coder en dur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public List<String> compareTo(Object o){
     
      List<String> retour = new List<String>();
      if (! o.getXXX().equals(this.getXXX()) )
        retour.add("XXX");
     
    ....
     
    }

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Bonjour, je n'arrive tjs pas a effectuer cette fonction...
    Il semble que les INTERCEPTOR en soit capable mais j'ai tjs un pb...
    J'ai bien rajouter dans spring l'interceptor sur la sessionFactory

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="entityInterceptor" ref="findDirtyFields" />
    		<property name="mappingDirectoryLocations">
    ....
    J'ai un point breakpoint sur la methode public int[] findDirty(Object entity, Serializable id,
    Object[] currentState, Object[] previousState,
    String[] propertyNames, Type[] types) {
    // TODO Auto-generated method stub

    return null;

    }

    Celle-ci est bien appelé lors de mon update cependant, les parametres currentState et previousState sont tous les 2 égaux aux nouvelles valeurs...
    Je ne comprendrais vraiment pas

    J'ai bien essayé ds le mapping l'attribut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select-before-update="true"
    Cela a pour effet que les parametres currentState et previousState sont sont tous les 2 égaux aux anciennes valeurs...

    Alors que la logique voudrait que j'ai 2 valeurs différentes!!!
    Si quelqu'un peux m'éclairer!!! Merciiii

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Quelqu'un

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 71
    Par défaut
    Ma solution ne te convient pas ?

  10. #10
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 890
    Par défaut
    Utilises-tu la dernière version d'hibernate ?

    Le code que je t'ai donné fonctionne très bien chez moi et c'est la seule manière d'intercepter les changements avant la persistence parmi les objets hibernate..

    Il y a une chose assez importante : tu dois récupérer l'objet que tu veux scanner d'abord dans ta session, faire les modifications sur l'objet, et ensuite, tu auras ton oldstate renseigné. Si tu fais autrement ça ne fonctionnera pas..

    Il faut qu'hibernate sache que tu as modifié un objet dans ta session, sinon il ne saura pas quels étaient les états précédents.

    Désolé mais je ne peux pas t'en dire plus, j'ai un peu galéré pour mettre cela en place, et j'espère que tu vas quand même réussir à le faire !

    A+

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Oui j'utilise la dernière version d'Hibernate la 3...

    Je viens réessayer mais ca ne marche tjs pas..
    Pourrais tu me mettre ton code que je vois comme tu a fais d'un peu plus pret... parce que la j'ai toujours currentState = previousState
    Donc la fonction ne sert à rien...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="entityInterceptor" ref="findDirtyFields" />
    ....

    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
    public class FindDirtyFields extends EmptyInterceptor {
     
    	@Override
    	public int[] findDirty(Object entity, Serializable id,
    			Object[] currentState, Object[] previousState,
    			String[] propertyNames, Type[] types) {
    		// TODO Auto-generated method stub
    		if (entity instanceof Application) {	
     
    			return super.findDirty(entity, id, currentState, previousState,
    					propertyNames, types);
    		}
    		return null;
     
    	}
     
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public void pressOkToUpdate(ActionEvent evt) {
    		Application application= service.listAllApplications().get(6); //récupère l'application à partir de la base.
    		mapProperties(application); //fait tous les set des nouvelles valeurs
    		update(application, evt); //sauvegarde
     
    	}
    Lors de l'update l'Interceptor est bien appelé...
    Je sais qu'il doit rester un problème mai je ne vois pas...

    Merci bcp pour l'aide déjà apportée

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/01/2012, 17h57
  2. récupérer le nom des attributs d'une classe
    Par danyboy85 dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 22/06/2006, 11h42
  3. Réponses: 2
    Dernier message: 03/02/2005, 13h21
  4. Réponses: 11
    Dernier message: 16/10/2004, 18h14
  5. Réponses: 2
    Dernier message: 20/08/2004, 17h10

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