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 :

Deux objets avec le même identifiant pour une session


Sujet :

Hibernate Java

  1. #1
    Membre régulier
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    171
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 171
    Points : 78
    Points
    78
    Par défaut Deux objets avec le même identifiant pour une session
    Bonjour,

    Je suis entrain de réaliser des tests sur une méthode de mise à jour. Mais quand je l'exécute j'ai une DataAccessException :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a different object with the same identifier value was already associated with the session: [domain.model.Clients#173]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [domain.model.Clients#173]
    Voilà le code de ma méthode de test (j'utilise JUnit pour les tests et Spring pour l'injection des dépendances)
    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
    @Test
    	public void testUpdateClient() {
    		/** met à jour un client qui existe */
    		// ajout d'un nouveau client en vérifiant qu'il n'existe pas avant
    		Clients clientAUpdater = new Clients("referenceTest2", "nomTest2",
    				"adresseTest2", "adresseFacturationTest2",
    				"adresseLivraisonTest2", "conditionsPaiementTest2",
    				"telephoneTest2", "mailTest2", "numereoTest2");
    		boolean existePas = this.clientsManager.clientExiste(clientAUpdater
    				.getNom());
    		assertFalse(existePas);
    		this.clientsManager.sauvegarderClient(clientAUpdater);
    		// mise à jour du client
    		clientAUpdater.setAdresse("");
    		clientAUpdater.setAdresseFacturation("");
    		clientAUpdater.setMail("");
    		this.clientsManager.updateClient(clientAUpdater);
    		// récupère les données du client mis à jour et on teste que les valeurs
    		// du client mis à jour sont les mêmes que celle qui ont été passées.
    		Clients clientUpdate = this.clientsManager.getClient("nomTest2");
    		assertEquals("", clientUpdate.getAdresse());
    		assertEquals("", clientUpdate.getAdresseFacturation());
    		assertEquals("", clientUpdate.getMail());
    Donc la mise à jour de clientAUpdater ne se fait pas. Ce qui suit est le code de la méthode de mise à jour d'un client, de la couche DAO de mon appli :
    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
    public void updateSecteursActivite(SecteursActivite secteurActiviteAMettreAJour) {
    		try {
    			if (secteurActiviteAMettreAJour != null
    					&& !secteurActiviteAMettreAJour.getNom().equals("")) {
    				// récupération de la session du secteur d'activité ou création d'une
    				// nouvelle
    				logger.info("mise à jour du secteur d'activité "+ secteurActiviteAMettreAJour.getNom());
     
    				// mise à jour du secteur d'activité grâce à hibernate :
    				// autorisé grâce à "@Transactional (readOnly=false)" de la
    				// couche service
    				getHibernateTemplate().update(secteurActiviteAMettreAJour);
    			} else {
    				logger.error("Sur la méthode updateSecteursActivite");
    				throw new IllegalArgumentException(
    						"méthode updateSecteursActivite : secteurActiviteAMettreAJour null !");
    			}
     
    		} catch (DataAccessException e) {
    			logger.error("Exception - DataAccesException : " + e.getMessage()
    					+ " sur la méthode updateSecteursActivite");
    		}
    	}
    Quelqu'un peut-il me dire ce qui ne va pas dans ma méthode de test ?

    En vous remerciant,
    Nicolas

  2. #2
    Expert confirmé
    Avatar de X-plode
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2005
    Messages
    682
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2005
    Messages : 682
    Points : 4 883
    Points
    4 883
    Par défaut
    Salut,


    Au niveau de ta méthode getnom es tu sur qu il te retourne un boolean ?

    Sinon as tu vérifier l état de ton boolean ?

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    peux tu nous dire à quelle ligne tu as ton exception?

  4. #4
    Membre régulier
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    171
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 171
    Points : 78
    Points
    78
    Par défaut
    Bonjour,

    X-plode, oui, je suis sur de ma méthode getNom : elle me renvoie bien le nom clientAUpdater et le boolean renvoyé est correct.

    J'ai l'erreur à la ligne suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.clientsManager.updateClient(clientAUpdater);
    Je pense savoir d'où vient l'erreur. Donc, préalablement, je sauve mon clientAUpdater, puis ensuite je l'update. Je pense que dans un premier temps dans la méthode sauvegarderClient je créé l'objet dans la session hibernate, et ensuite quand j'utilise updateClient il veut créer un autre même objet, au lieu de réutiliser celui qui existe déjà.
    Un petit détail, j'ai utilisé le tuto suivant pour la couche dao et la couche service :
    http://baptiste-meurant.developpez.c...ing-hibernate/

    J'ai réglé le problème en changeant le code de updateClient : je clear la session hibernate avant de faire appel à getHibernateTemplate().update

    Voilà mon nouveau code :
    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
    public void updateClient(Clients client) {
    	try {
    		if (client != null && !client.getNom().equals("")) {
    			// récupération de la session du client ou création d'une
    			// nouvelle
    			logger.info("mise à jour du cient "
    						+ client.getNumEntrepriseClient() + " "
    						+ client.getNom());
     
    			// mise à jour du client grâce à hibernate: autorisé grâce à "@Transactional (readOnly=false)" de la
    			// couche service
    			getHibernateTemplate().clear();
    			getHibernateTemplate().update(client);
    		} 
    		else {
    			logger.error("Sur la méthode updateClient");
    			throw new IllegalArgumentException(
    					"méthode updateClient : client null !");
    		}
     
    	} catch (DataAccessException e) {
    		logger.error("Exception - DataAccesException : " + e.getMessage()
    					+ " sur la méthode updateClient");
    	}
    }
    Mais je ne connais pas les risque d'utiliser clear. Qu'en pense vous, ais-je choisi la bonne solution ?

    Nicolas

  5. #5
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Je n'ai pas tout lu en détails, mais si ton objet est toujours dans la session après création, tu n'as même pas besoin de faire un update, les modifications seront prises en compte au commit de ta transaction.

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    ton problème je pense à la base était que tu n'utilisat pas une nouvelle session hibernate pour chaque méthode test. Hors tu dois bien partir à chaque fois d'une nouvelle session avec une nouvelle session factory et une nouvelle db le tout crée dans setUp, sinon tu va avoir des effets de bord comme celui là entre test test.

    (ici tu donnais à ton objet Client un id qui était déjà présent dans la session de part un autre objet client créé par un autre test)

  7. #7
    Membre régulier
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    171
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 171
    Points : 78
    Points
    78
    Par défaut
    ah ok je comprends mieux. Je vais revoir le code et arranger tout ça maintenant que c'est clair.

    En tout cas merci à vous tous.

    Nicolas

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 14/04/2020, 21h03
  2. Réponses: 2
    Dernier message: 31/10/2011, 14h48
  3. Souci pour comparer deux objets avec equals()
    Par xillibit dans le forum Langage
    Réponses: 7
    Dernier message: 30/09/2007, 16h41
  4. Réponses: 2
    Dernier message: 03/09/2007, 16h50
  5. Réponses: 0
    Dernier message: 10/08/2007, 22h42

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