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 :

Probleme autoincrement id


Sujet :

Hibernate Java

  1. #21
    Invité
    Invité(e)
    Par défaut
    Bonjour.

    1/
    Sur certains sites, j'ai vu que l'update était différent :
    lors de l'appel à monObjetDAO.updateObjet(monobjetmodifié).
    la méthode à l'intérieur était :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    monobjet2 = ..getSession().get(monobjetmodifié.getId)
    monobjet2.setTousLesValeurs(monobjetmodifié)
    update(monobjet2);
    2/Dans votre exemple avec clientDAO, je ne vois pas non plus de close()?

    3/ Sur le support Hibernatehttps://docs.jboss.org/hibernate/cor...e-saveorupdate, ils parlent de la methode saveOrUpdate(), celle-ci ne peut pas résoudre le probleme?

    4/Comme demandé, Voici mon code qui permet de voir la cinématique générale :
    fichier struts 2
    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
    		<!-- Acces aux Locataires via le menu -->
    		<action name="Locataire" class="cpte.pages.admin.locataire.PageLocataireAction">
              <result name="success" type="redirectAction">LocatairesConsulter</result>
            </action>
            <!-- Locataires : consulter les Locataires -->
            <action name="LocatairesConsulter" class="cpte.pages.admin.locataire.PageLocataireAction" method="consulterLocataires">
                <result>/pages/admin/locataire/pageLocatairesConsulter.jsp</result>
            </action>
     
            <!-- Locataires : modifier un locataire -->
            <action name="LocataireModifier" class="cpte.pages.admin.locataire.PageLocataireAction" method="loadLocataire">
                <result name="success">/pages/admin/locataire/pageLocataireModifier.jsp</result>
                <result name="input">/pages/admin/locataire/pageLocataireModifier.jsp</result>
            </action>
      		<!-- Tarifs : modifier un locataire / valider -->
    	    <action name="LocataireModifierValider" class="cpte.pages.admin.locataire.PageLocataireAction" method="validerLocataire">
          		<result name="input">/pages/admin/locataire/pageLocataireModifier.jsp</result>
          		<result name="success" type="redirectAction">
          			<param name="actionName">LocatairesConsulter</param>
          		</result>
    	    </action>
    fichier de mapping d'un locataire :
    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
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 28 f?vr. 2014 16:38:27 by Hibernate Tools 3.4.0.CR1 -->
    <hibernate-mapping>
        <class name="cpte.hibernate.CpteLocataire" table="CPTE_LOCATAIRE">
            <id name="locId" type="long">
                <column name="LOC_ID" precision="22" scale="0" />
                <generator class="increment"></generator>
            </id>
            <property name="locCodeClient" type="long">
                <column name="LOC_CODE_CLIENT" precision="22" scale="0" not-null="true" />
            </property>
            <property name="locRaisonSociale" type="string">
                <column name="LOC_RAISON_SOCIALE" length="80" not-null="true" />
            </property>
            <property name="locDateEffet" type="date">
                <column name="LOC_DATE_EFFET" length="7" not-null="true" />
            </property>
            <property name="locDateFin" type="date">
                <column name="LOC_DATE_FIN" length="7" />
            </property>
            <property name="locExterne" type="boolean">
                <column name="LOC_EXTERNE" precision="1" scale="0" not-null="true" />
            </property>
        </class>
    </hibernate-mapping>

    Première action, j'affiche les locataires via la methode "consulterLocataires":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	public String consulterLocataires()
    	{
    		listeLocataires = CpteLocataireDao.getInstance().listAll();
    		return SUCCESS;
    	}
    J'arrive donc sur une page contenant un tableau avec un lien modifier en fin de chaque ligne. Voici le jsp :
    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
     
    <c:forEach var="locataire" items="${listeLocataires}" varStatus="status">
     
     
    					<tr>
    						<td>${locataire.locId}</td>
    						<td>${locataire.locCodeClient}</td>
    						<td>${locataire.locRaisonSociale}</td>
    						<td><fmt:formatDate  pattern="dd/MM/yyyy"  value="${locataire.locDateEffet}"/></td>
    						<td><fmt:formatDate  pattern="dd/MM/yyyy"  value="${locataire.locDateFin}"/></td>
    						<td>${locataire.locExterne}</td>
    						<td>
    							<a href="LocataireModifier?locataire.locId=${locataire.locId}"> <s:text
    										name="%{getText('label.modifier')}" />
    								</a>
    						</td>
    					</tr>
     
    				</c:forEach>
    Lorsque je clique sur le lien modifier, la methode "loadLocataire" est appelée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public String loadLocataire() throws Exception
        {
    		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
    		long locataireId = Long.parseLong(request.getParameter("locataire.locId"));
    		//tarif = new TarifDAO().findById(listeTarifs,tarifId);
    		locataire = CpteLocataireDao.getInstance().get(locataireId); 
    		if(locataire==null)
    		{
    			addActionError(getText("error.baseDeDonnees"));
    			return INPUT;
    		}
    		return SUCCESS;
        }
    J'arrive lors sur la page jsp permettant d'afficher le locataire et donc de modifier les différentes valeurs :
    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
    <s:form name="locataireForm" >
    				<s:textfield name="locataire.locId" readonly="true" required="true"
    					label="%{getText('label.locataire.id')}" />
    				<s:textfield name="locataire.locCodeClient" required="true"
    					label="%{getText('label.locataire.codeClient')}" />
     
    				<s:textfield name="locataire.locRaisonSociale" required="true"
    					label="%{getText('label.locataire.raisonSociale')}" />
     
    				<s:textfield name="locataire.locDateEffet" required="true" id="locataire_dateEffet" 
    					label="%{getText('label.locataire.dateEffet')}" />
    				<s:textfield name="locataire.locDateFin" id="locataire_dateFin"
    					label="%{getText('label.locataire.dateFin')}" />
     
    				<s:checkbox name="locataire.locExterne" required="true"
    					label="%{getText('label.locataire.locataireExterne')}" labelposition="left"/>
     
               </s:form>
    Lorsque je valide, la methode "validerLocataire" est appelée, donc voici le code complet :
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    public String validerLocataire() throws Exception
    	 {
    		 String codeRetour=INPUT;
    		 CpteLocataire locataireAvecMemeRaisonSociale = CpteLocataireDao.getInstance().findByRaisonSociale(locataire.getLocRaisonSociale());
     
    		 if(locataire.getLocId()==0)
    		 {
    			 log.debug("validation creation d'un locataire");
    			 //Vérification qu'un locataire n'existe pas avec la meme raisonSociale
    			 if(locataireAvecMemeRaisonSociale != null)
    			 {
    				 addActionError(getText("error.locataire.locataireExistant"));
    			 }
     
    			 if(hasErrors() == false)
    			 {
    				 //Par défaut, la date de debut sera egale à la date du jour, si elle n'est pas renseignee
    				 if(locataire.getLocDateEffet()==null)
    				 {
    					 locataire.setLocDateEffet(new Date());
    				 }
    				 log.debug("creation du locataire : "+locataire.getLocRaisonSociale());
    				 try
    				 {
    					 HibernateUtil.currentSession().beginTransaction();
    					 CpteLocataireDao.getInstance().save(locataire);
    					 HibernateUtil.currentSession().getTransaction().commit();
    					 codeRetour=SUCCESS;
    				 }
    				 catch (HibernateException e)
    				 {
    					 codeRetour=INPUT;
    					 log.error(Util.getStackTrace(e));
    				 }
    			 }
    		 }
    		 else
    		 {
    			 log.debug("validation modification du locataire");
    			 //TODO controle modification locataire : si contrats --> alors modif codeClient/raisonsociale/dateeddet interdite
     
    			 //Vérification qu'un locataire n'existe pas avec la meme raisonSociale pour un id différent
    			 if(locataireAvecMemeRaisonSociale != null && locataireAvecMemeRaisonSociale.getLocId() != locataire.getLocId())
    			 {
    				 addActionError(getText("error.locataire.locataireExistant"));
    			 }
     
    			 if(hasErrors() == false)
    			 {
    				 log.debug("mise à jour du locataire : "+locataire.getLocRaisonSociale());
    				 try
    				 {
    					 HibernateUtil.currentSession().beginTransaction();
    					 CpteLocataireDao.getInstance().update(locataire);
    					 HibernateUtil.currentSession().getTransaction().commit();
    					 codeRetour=SUCCESS;
    				 }
    				 catch (HibernateException e)
    				 {
    					 codeRetour=INPUT;
    					 log.error(Util.getStackTrace(e));
    				 }
     
    			 }
     
    		 }
     
    		 if(hasErrors()==false && INPUT.equals(codeRetour))
    		 {
    			 addActionError(getText("error.baseDeDonnees"));
    		 }
     
    		 return codeRetour;
    	 }
    Pour votre information, voici le code de la methode findByRaisonSociale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        public CpteLocataire findByRaisonSociale(String raisonSociale)
       	{
        	CpteLocataire locataire = null;
        	Criteria query = getHibernateSession().createCriteria(clazz);
        	query.add(Restrictions.eq( "locRaisonSociale", raisonSociale));
        	@SuppressWarnings("unchecked")
    		List<CpteLocataire> listeLocataires = query.list();
        	if(listeLocataires.isEmpty() == false)
        	{
        		locataire=listeLocataires.get(0);
        	}
        	return locataire;
       	}

    J'espère que ce code pourras vous aider. Celui-ci étant pour l'instant très simple, vu que ce n'est qu'une lecture puis modification

  2. #22
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    A ce que je vois, c'est du struts 2, je me trompe ?
    Dans mon exemple, effectivement, il n'y a pas l'ouverture/fermeture de la session parce que c'est géré au niveau d'un filtre.
    La session est ouverte en début de request et fermée en fin de response.

    La méthode saveOrUpdate est censée se charger de distinguer une modification d'une création, personnellement, je préfère invoquer 2 méthodes distinctes en fonction du cas géré par la couche application...
    Si je suis censé modifier un enregistrement et qu'il n'existe plus, j'aime autant avoir une erreur que de créer un nouvel enregistrement de façon transparente. De même si je créé un enregistrement et qu'entre temps il est ajouté... ça peut se discuter... mais imagine que la table ait un id auto-généré avec un label et un code. L'utilisateur A créé un code AA -> Mon label AA et l'utilisateur B créé un code AA -> Mon label BB.
    A la fin, on aura AA -> Mon label BB mais l'utilisateur B n'a aucune idée d'avoir écrasé un enregistrement.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #23
    Invité
    Invité(e)
    Par défaut
    En effet c'est du struts 2.
    Pour essayer de mettre hibernate, j'ai juste remplacé mes DAO "manuelles" (avec mon propore sql) par celles de hibernate (en suivant votre exemple).
    Je n'ai rien fait de particulier en plus.

  4. #24
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Il faut en fin de cycle fermer la session Hibernate, et normalement, il n'y aura plus de problème
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #25
    Invité
    Invité(e)
    Par défaut
    Bonjour.

    Suite à votre réponse :
    Il faut en fin de cycle fermer la session Hibernate, et normalement, il n'y aura plus de problème
    j'ai donc rajouté à la fin de chaque méthode de l'action struts 2 (avant de faire return success) :
    HibernateUtil.closeSession();

    exemple :
    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
    	public String consulterLocataires()
    	{
    		listeLocataires = CpteLocataireDao.getInstance().listAll();
    		HibernateUtil.closeSession();
    		return SUCCESS;
    	}
     
     
    	public String loadLocataire() throws Exception
        {
    		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
    		long locataireId = Long.parseLong(request.getParameter("locataire.locId"));
    		//tarif = new TarifDAO().findById(listeTarifs,tarifId);
    		locataire = CpteLocataireDao.getInstance().get(locataireId); 
    		if(locataire==null)
    		{
    			addActionError(getText("error.baseDeDonnees"));
    			return INPUT;
    		}
    		HibernateUtil.closeSession();
    		return SUCCESS;
        }
    Maintenant ca marche bien, l'update fait bien un update en base sans faire d'erreur.

    Par contre, je remarque qu'à chaque appel à un get(), hibernate fait une requete sql alors qu'avant, hibernate n'en faisait pas (surement une histoire de cache hibernate).
    Est-ce normal?
    et surtout est-ce le fonctionnement logique (recommandé)? (En même temps si ce n'est pas recommandé, ca ne marchait pas avant que vous m'indiquiez de rajouter cette ligne )

    Deuxièmement :
    Je suppose qu'il ne faut pas mettre le HibernateUtil.closeSession(); directement dans les DAO, afin de pouvoir faire plusieurs requetes dans la même session hibernate si on enchaine des requetes. Ai-je raison?

    cdt

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Oui il est normale d'avoir des get pour chaque session. Après tout, si deux utilisateurs travaillent en même temps, tu ne veux pas que l'utilisateur 1 voie le résultat partiel du travail de l'utilisateur 2. C'est le principe de l'isolation entre les transactions qui joue. Chaque requete http a sa propre transaction => pour l'isolation, chaque requete http interroge la base.

  7. #27
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par johannsan Voir le message
    Par contre, je remarque qu'à chaque appel à un get(), hibernate fait une requete sql alors qu'avant, hibernate n'en faisait pas (surement une histoire de cache hibernate).
    Est-ce normal?
    et surtout est-ce le fonctionnement logique (recommandé)? (En même temps si ce n'est pas recommandé, ca ne marchait pas avant que vous m'indiquiez de rajouter cette ligne )
    Oui, c'est le fonctionnement normal.
    Avant, l'entité restait "attachée" au contexte de session, inutile donc de recharger puisque l'objet existe déjà en mémoire.
    Avec Hibernate (et JPA), on a 3 états d'une entité :
    - attachée : l'objet existe en DB et est lié à une session active, toute modification de l'objet sera répercutée en DB
    - détachée : l'objet existe en DB mais n'est plus rattaché à une session active, toutes les modifications seront perdues
    - transient : l'objet n'existe pas en DB (on vient de faire un new Objet()...)
    Citation Envoyé par johannsan Voir le message
    Deuxièmement :
    Je suppose qu'il ne faut pas mettre le HibernateUtil.closeSession(); directement dans les DAO, afin de pouvoir faire plusieurs requetes dans la même session hibernate si on enchaine des requetes. Ai-je raison?
    Ce n'est pas qu'on ne peut pas, mais effectivement, ce n'est pas la meilleure façon de faire.
    Dans un contexte web, on lie généralement la session (hibernate) à un request/response. Au delà, ça n'a pas de sens de la garder dans la mesure où le serveur ne peut pas savoir si le client est toujours à l'autre bout du fil.
    Avec Struts1, j'utilise un "pré-processeur" de requêtes pour ouvrir la session, enchaîner les contrôleurs et finir par le rendu de la page avant de revenir dans le pré-processeur et de fermer la session.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #28
    Invité
    Invité(e)
    Par défaut
    Merci beaucoup pour toutes ces explications

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. probleme champ autoincrement
    Par Daniela dans le forum Modélisation
    Réponses: 1
    Dernier message: 23/12/2010, 12h37
  2. probleme avec le champs de type "autoincrement"
    Par hayat2 dans le forum Bases de données
    Réponses: 2
    Dernier message: 09/05/2010, 10h28
  3. Probleme avec autoincrement Mysql Jsf
    Par dalidali86 dans le forum Requêtes
    Réponses: 0
    Dernier message: 10/09/2009, 01h18
  4. Réponses: 4
    Dernier message: 25/11/2008, 19h34
  5. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 15h50

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