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 :

Comment savoir le résultat d'un update ?


Sujet :

Hibernate Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    442
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 442
    Par défaut Comment savoir le résultat d'un update ?
    Bonjour

    La javadoc nous dit:

    update

    public void update(Object object)
    throws HibernateException

    Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown. This operation cascades to associated instances if the association is mapped with cascade="save-update".

    Parameters:
    object - a detached instance containing updated state
    Throws:
    HibernateException
    Et dans mon code, si j'update un objet qui n'existe pas en base, aucune exception n'est levée Et il n'y a pas de valeur de retour indiquant le résultat de l'update.

    Les bras m'en tombent quelque peu...

    Suis-je obligé de remplacer mon "hibernateSession.update(objet)" par une requête HQL "à la main" ?

    [Edit] pareil pour le delete... au secours

  2. #2
    Membre Expert Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Par défaut
    Pour mettre a jour un objet, on utilise plutot saveOrUpdate.
    Cette methode levera une exception si ton objet n'existe pas.

    En effet update leve une exception seulement si il y'a un probleme d'integrite referentielle.
    D'ailleurs cette methode est deprecated(depuis la version 3 je crois)

  3. #3
    Membre Expert Avatar de maxf1
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 229
    Par défaut
    Citation Envoyé par Jung
    Bonjour

    La javadoc nous dit:

    Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown. This operation cascades to associated instances if the association is mapped with cascade="save-update".
    Et dans mon code, si j'update un objet qui n'existe pas en base, aucune exception n'est levée Et il n'y a pas de valeur de retour indiquant le résultat de l'update.

    Les bras m'en tombent quelque peu...

    la javaDoc t'indique juste qu'il y aura une exception de levé si une instance avec le meme identifiant existe DEJA. Donc s'il n'en existe pas pas d'exception.

    Mais comme la si bien dit willoi, utilise saveOrUpdate.
    CEtte méthode fera le save si ton object n'existe pas. Ou Update s'il existe et que tu veux le modifier.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    442
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 442
    Par défaut
    Merci pour vos réponses mais je ne peux pas utiliser saveOrUpdate, j'ai besoin de les séparer clairement (contraintes fonctionnelles).

    Donc pas de solution à part une requête HQL...

  5. #5
    Membre Expert Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Par défaut
    Citation Envoyé par Jung
    Merci pour vos réponses mais je ne peux pas utiliser saveOrUpdate, j'ai besoin de les séparer clairement (contraintes fonctionnelles).

    Donc pas de solution à part une requête HQL...
    Tu peux te definir une methode qui utilise save pour une creation et une methode qui utilise refresh et saveOrUpdate pour une modification et ainsi cela respectera tes contraintes fonctionnelles.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public void save(TonBean bean) throrws HibernateException{
    session.save(bean);
    }
     
    public void edit(TonBean bean) throrws HibernateException{
    session.refresh(bean);
    session.saveorUpdate(bean);
    }

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    Citation Envoyé par Jung
    Merci pour vos réponses mais je ne peux pas utiliser saveOrUpdate, j'ai besoin de les séparer clairement (contraintes fonctionnelles).

    Donc pas de solution à part une requête HQL...
    Salut,
    Peux-tu nous dire quelles sont ces contraintes fonctionnelles ? Parce qu'à mon avis la méthode saveOrUpdate() ferait bien l'affaire, étant donné qu'elle ajoute ou met à jour selon que l'entité existe déjà ou pas. Tu as besoin d'une exception levée pour effectuer quelle sorte de traitement en cas d'erreur d'update ?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    442
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 442
    Par défaut
    Citation Envoyé par manblaizo
    Peux-tu nous dire quelles sont ces contraintes fonctionnelles ? Parce qu'à mon avis la méthode saveOrUpdate() ferait bien l'affaire, étant donné qu'elle ajoute ou met à jour selon que l'entité existe déjà ou pas. Tu as besoin d'une exception levée pour effectuer quelle sorte de traitement en cas d'erreur d'update ?
    L'utilisateur a un écran avec les champs de la table éditables

    - il peut cliquer sur "create":
    • s'il n'a pas renseigné le champ de la clé primaire (seul champ not null) --> message d'erreur 1
    • si l'enregistrement existe déjà --> message d'erreur 2
    • sinon --> message de confirmation que la création a bien eu lieu

    - il peut cliquer sur "update":
    • s'il n'a pas renseigné le champ de la clé primaire (seul champ not null) --> message d'erreur 3
    • si l'enregistrement n'existe pas --> message d'erreur 4
    • sinon --> message de confirmation que l'update s'est bien passée


    Difficile de faire plus simple mais je suis débutant avec Hibernate

  8. #8
    Membre Expert Avatar de maxf1
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 229
    Par défaut
    Fait un get() sur la clé primaire ainsi tu verra s'il existe. S'il existe et qu'il fait à cliquer sur save alors tu leves une exception. Et si get ne renvoi rien et qu'il a cliquer sur update alors la aussi une exception.


    Pourquoi faire 2 message différent pour 2 cas identique (clé primaire non renseigné)?

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    442
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 442
    Par défaut
    Citation Envoyé par maxf1
    Pourquoi faire 2 message différent pour 2 cas identique (clé primaire non renseigné)?
    Oui ce sera surement le même message mais je me méfie des utilisateurs, des fois qu'ils voudraient faire la distinction

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    Eh bien, je pense qu'il y a un problème de conception au départ. La clé primaire sert avant tout pour les besoins de ton application, tu ne devrais donc pas la laisser gérer par l'utilisateur. Parce que, si j'ai bien compris ta description, c'est l'utilisateur qui choisit ce qui sera la valeur de la clé primaire et donc tu vérifies s'il n'existe pas déjà une entité avec la même valeur pour lever une exception lors de la création. Pareil pour l'update, qui suppose que l'utilisateur doit connaitre à l'avance la clé primaire de l'élément à mettre à jour, ce qui n'est pas très réaliste à mon avis.
    La génération de la clé primaire devrait être entièrement gérée par toi, en la déléguant à Hibernate par exemple. Et là, une création signifierait bien "partir de rien", donc clé primaire null, et un appel à saveOrUpdate() résulterait en un insert dans la base de données. Pour les mises à jour, tu commences d'abord par afficher la liste des éléments à l'utilisateur qui pourra en sélectionner un, lui afficher l'écran de modification, puis enregistrer les modifications. Et comme la clé sera not null, saveOrUpdate() fera une mise à jour. C'est du CRUD classique... Le seul point c'est que c'est ton appli qui doit gérer les clés primaires et non l'utilisateur.
    Voilà, j'espère que ça aide.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    442
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 442
    Par défaut
    En effet manblaizo je suis tout à fait d'accord avec toi

    Tu n'imagines pas les horreurs que ma MOA me demande de faire...

    Cette clé primaire est également une clé étrangère, elle est bien générée (en partie) par hibernate lors de l'insert sur une première table. Le truc qu'on me demande, c'est que lorsque l'utilisateur a fait son insert dans cette première table, il obtient alors la clé qu'il peut utiliser pour faire un 2ème insert dans ma nouvelle table. La demande initiale était juste de rajouter des champs à la première table mais comme ce n'est pas possible (15 ans de développements en C, Cobol et autres à revoir) on m'a demandé de faire la deuxième table qui fait l'objet de ce topic. Voilà toute l'histoire... (j'appelle aussi des morceaux de C et de shell en java, je te laisse imaginer la gestion des transactions )

    Donc finalement j'aurais 2 méthodes (comme l'a écrit maxf1):
    • mySave: get puis save
    • myUpdate: get puis update

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    OK, je comprend ton problème alors, ça ne doit pas être facile de se trouver à ta place ... Et bien évidemment, l'ajout dans la première table ne passe pas par ton application, je suppose ?? Sinon, que dire, c'est quand trop risqué et sujet à des erreurs que de laisser les utilisateurs contrôler les liaisons entre les tables, car ça voudrait dire qu'ils doivent comprendre les mécanismes internes de l'application. Il faudrait surement encore creuser un peu pour avoir une solution plus élégante et moins risquée.

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    442
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 442
    Par défaut
    Citation Envoyé par manblaizo
    Il faudrait surement encore creuser un peu pour avoir une solution plus élégante et moins risquée.
    Oui sans doute mais il y a aussi la contrainte des délais

    J'ai finalement réussi !

    Alors, il y a une dernière astuce à savoir:

    • Mauvaise implémentation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void updateObject(ClassPojo pojoToUpdate) throws MyException {
    	ClassPojo newPojo = (ClassPojo) session.get(ClassPojo.class, pojo.getPrimaryKey());	
    	if (newPojo == null)
    		throw new MyException("Attention ça n'existe pas, donc pas d'update possible");
    	session.update(pojoToUpdate);
    	session.flush();
    }
    Cette mauvaise implémentation renvoie une erreur:
    org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.[...].ClassPojo#primaryKey]
    • Bonne implémentation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public void updateObject(ClassPojo pojoToUpdate) throws MyException {
    	ClassPojo newPojo = (ClassPojo) session.get(ClassPojo.class, pojo.getPrimaryKey());	
    	if (newPojo == null)
    		throw new MyException("Attention ça n'existe pas, donc pas d'update possible");
    	newPojo = (ClassPojo) session.merge(pojoToUpdate);
    	session.update(pojoToUpdate);
    	session.flush();
    }
    Il faut utiliser la fonction merge !

    à tous

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    Citation Envoyé par Jung
    Oui sans doute mais il y a aussi la contrainte des délais
    Oui tu as tout à fait raison, les fameux délais !! Mais parfois il vaut mieux passer un peu de temps à mieux sécuriser son application vis-à-vis des utilisateurs, plutôt que de se retrouver avec des incohérences dans sa base de données après quelques temps en production. Parce que là, rien n'empêcherait un utilisateur d'associer une de tes entités à une clé qui ne serait pas la bonne dans la première table... Mais bon, l'essentiel parfois c'est de faire fonctionner l'application au début et puis réfléchir sérieusement plus tard.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment savoir le résultat d'un requête
    Par janjannaj dans le forum Bases de données
    Réponses: 2
    Dernier message: 07/07/2010, 11h09
  2. Comment savoir si une requête retourne un résultat
    Par tomy29 dans le forum Hibernate
    Réponses: 2
    Dernier message: 06/11/2008, 10h18
  3. Réponses: 19
    Dernier message: 26/01/2005, 10h41
  4. Réponses: 9
    Dernier message: 11/03/2003, 12h22
  5. Réponses: 4
    Dernier message: 10/09/2002, 17h09

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