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

Développement Web en Java Discussion :

récupérer le max(id)


Sujet :

Développement Web en Java

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2012
    Messages : 82
    Points : 61
    Points
    61
    Par défaut récupérer le max(id)
    Bonjour tout le monde,

    Je suis tout nouveau avec hibernate, mon problème c'est que je veux récupérer le max(id) et le retourner voici mon code clientDaoImp.java:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public int mId(){
    		Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
    		Client c = (Client) session.createQuery("select max(id) from utilisateur");
    		session.flush();
    		return c.getId();
    	}
    voici le clientManagerImp.java:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public int idDao(){
    		return clientDao.mId();
    	}

    Et je l'appelle dans la classe ClientAction "id = clientManager.idDao()+1;" , l'erreur qui apparaît est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    org.hibernate.hql.ast.QuerySyntaxException: utilisateur is not mapped [select max(id) from utilisateur]
    	org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:158)
    	org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:87)
    	org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:70)
    .
    .
    .
    .
    Si quelqu'un pourrait m'aider à résoudre cette énigme
    MErci

  2. #2
    Membre chevronné
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Points : 2 112
    Points
    2 112
    Par défaut
    Utilisateur, avec un grand U, car il s'agit d'une classe.

    Cela étant c'est une très mauvaise pratique de récupérer le max id.
    Pourquoi cherches-tu à faire cela ?
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2012
    Messages : 82
    Points : 61
    Points
    61
    Par défaut
    Citation Envoyé par fxrobin Voir le message
    Utilisateur, avec un grand U, car il s'agit d'une classe.

    Cela étant c'est une très mauvaise pratique de récupérer le max id.
    Pourquoi cherches-tu à faire cela ?
    Re bonjour ^^
    Je réctifie, à la place de "utilisateur" je met client, bon j'ai modifier le c par un C majiscule et ça a ma donné ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    java.lang.ClassCastException: org.hibernate.impl.QueryImpl cannot be cast to ma.hibernate.Client
    	ma.dao.imp.ClientDaoImp.mId(ClientDaoImp.java:31)
    	ma.service.imp.ClientManagerImp.idDao(ClientManagerImp.java:21)
    	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	java.lang.reflect.Method.invoke(Method.java:597)
    Et pour répondre à ta question, en fait j'utilise oracle 10g, donc je pourrais pas faire un autoIncrement, c'est pour cela j'ai choisi de faire cette méthode

  4. #4
    Membre chevronné
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Points : 2 112
    Points
    2 112
    Par défaut
    L'auto incrément fonctionne très bien avec Oracle 10g et Hibernate (quelle version), mais il te faut créer une séquence et faire pointer le générateur d'ID sur cette séquence.

    Voici un lien qui pourra t'aider :
    http://blog.lishman.com/2009/02/auto...in-oracle.html

    sinon pour ton problème "createQuery" ne lance pas la requête il fait juste que la créer. Ca va donc dans un objet de type "Query" ... ton cast est donc incorrect, ce que te dit clairement ton erreur.
    Exemple : http://www.javabeat.net/2008/07/thre...-in-hibernate/

    Ensuite ta query il te faudra la lancer "list" ou "uniqueResult" (dans ton cas) pour obtenir ce que tu attends (et lancer la requête).

    Enfin, sur le fond, la méthode est mauvaise, car si tu es en mode "application" web (avec plusieurs clients potentiels) il est tout à fait probable que l'ID que tu récupères à un instant T pour en faire un auto-incrément rentre en concurrence avec un autre thread et donc tu auras un problème d'ID. Ne sous-estime pas cette possibilité de concurrence, elle commence à être élevée à partir d'une vingtaine d'utilisateurs.
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par xoftob Voir le message
    Et pour répondre à ta question, en fait j'utilise oracle 10g, donc je pourrais pas faire un autoIncrement
    A crotte alors, on m'aurais mentis, les applications que je maintiens depuis des années sur oracle ne marcheraient pas en fait?

    Oracle supporte très bien la gestion automatique des id via les sequences et hibernate intègre ça très bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    @Entity
    @Table(name="PROJECT_X")
    public class XProject {
        @Id 
        @SequenceGenerator(name="X_SEQ", sequenceName="X_SEQ")
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "X_SEQ")
        @Column(name = "X_ID")
        private Long id;

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2012
    Messages : 82
    Points : 61
    Points
    61
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    A crotte alors, on m'aurais mentis, les applications que je maintiens depuis des années sur oracle ne marcheraient pas en fait?
    En fait ça m'est paru bizarre cette information venu de mon encadrant (peut être quelque chose m'a échappé), mais j'ai bel est bien cherché et essayé de rendre l'id autoIncrement en vain, je travaille sur SQL Navigator 4.4 et je suis tout nouveau à comprendre tout ce qui est en rapport avec la technologie JEE (je fais l'auto-formation )

    @fxrobin
    sinon pour ton problème "createQuery" ne lance pas la requête il fait juste que la créer. Ca va donc dans un objet de type "Query" ... ton cast est donc incorrect, ce que te dit clairement ton erreur.
    Exemple : http://www.javabeat.net/2008/07/thre...-in-hibernate/
    J'ai compris ici qu'il faut déclarer un Query comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Query q = session.createQuery("select max(id) from Client");
    Après il faut exécuter la requête (quelle est la méthode pour?)

    Et à propos de:
    Ensuite ta query il te faudra la lancer "list" ou "uniqueResult" (dans ton cas) pour obtenir ce que tu attends (et lancer la requête).
    Jai ajouter le "uniqueResult" et ça me donne toujours la même erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Client c = (Client) session.createQuery("select max(id) from Client").uniqueResult();
    Merci

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    le mot clé autoincrement n'existe que dans mysql il me semble. En oracle comme avec pas mal d'autre DB, on utilise des sequences et de triggers pour assigner les id automatiquement.

    Ce serait quand même malheureux de ne pas avoir ce genre de support sur une DB qui se chiffres en dixaines de k€ / an


    Si tu ne compte pas insérer autrement que par hibernate, tu utilise les annotations en exemple et tu laisse hibernate créer le shéma.

    Si tu compte rendre ça automatique aussi en console sql, alors il faut ajouter des triggers. A partir de là deux possibilité

    trigger systématique, et il faudra au niveau hibernate lui dire d'utiliser le rownum pour récupérer l'id après insertion ou

    chose que je trouve plus simple: le trigger ne génère que si on a pas explicitement mis d'id, et hibernate configuré pour utiliser explicitement la sequence

  8. #8
    Membre chevronné
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Points : 2 112
    Points
    2 112
    Par défaut
    Citation Envoyé par xoftob Voir le message
    Jai ajouter le "uniqueResult" et ça me donne toujours la même erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Client c = (Client) session.createQuery("select max(id) from Client").uniqueResult();
    tu n'as pas placé correctement des parenthèses pour ton cast
    en plus le type retour n'est pas un Client.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Long id  = (Long) (session.createQuery("select max(id) from Client").uniqueResult());
    car ta requête va te retourner un ID, pas un client ! (en supposant que celui-ci est de type Long). Peux-tu montrer ta classe "Client" ?
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2012
    Messages : 82
    Points : 61
    Points
    61
    Par défaut
    Citation Envoyé par fxrobin Voir le message
    tu n'as pas placé correctement des parenthèses pour ton cast
    en plus le type retour n'est pas un Client.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Long id  = (Long) (session.createQuery("select max(id) from Client").uniqueResult());
    car ta requête va te retourner un ID, pas un client ! (en supposant que celui-ci est de type Long). Peux-tu montrer ta classe "Client" ?

    C'est résolu, merci beaucoup fxrobin! enfait à la place de long j'ai mis un bigDecimal et ça marche maintenant

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2012
    Messages : 82
    Points : 61
    Points
    61
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Si tu ne compte pas insérer autrement que par hibernate, tu utilise les annotations en exemple et tu laisse hibernate créer le shéma.
    tchize: un petit exemple s'il c'est pas trop demandé parce que là je commence à perdre le fil

    Si tu compte rendre ça automatique aussi en console sql, alors il faut ajouter des triggers. A partir de là deux possibilité
    J'ai essayé la solution du trigger que je viens de l'ajouter parmi mes connaissances :p est ce que ça doit être comme ça? Parce que ça m'a donné une erreur!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TRIGGER PR_ID_CLIENT
    BEFORE INSERT 
    ON CLIENT
    UPDATE NEW 
    SET ID = ID + 1
    Merci beaucoup tchize

  11. #11
    Membre chevronné
    Avatar de fxrobin
    Homme Profil pro
    Architecte SI, Java Fan, API Manager
    Inscrit en
    Novembre 2007
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte SI, Java Fan, API Manager
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2007
    Messages : 875
    Points : 2 112
    Points
    2 112
    Par défaut
    Citation Envoyé par xoftob Voir le message
    C'est résolu, merci beaucoup fxrobin! enfait à la place de long j'ai mis un bigDecimal et ça marche maintenant
    De rien, mais ça m'embête de t'avoir donné une solution à une approche "pas propre"
    Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par xoftob Voir le message
    tchize: un petit exemple s'il c'est pas trop demandé parce que là je commence à perdre le fil
    Déjà donné:

    http://www.developpez.net/forums/d12...d/#post6988992

    J'ai essayé la solution du trigger que je viens de l'ajouter parmi mes connaissances :p est ce que ça doit être comme ça? Parce que ça m'a donné une erreur!
    JE te donne ça demain, je fais toujours un copier coller du même code au boulot, vu le nombre monumental de fois par an où je dois créer des nouvelles tables avec trigger

  13. #13
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2012
    Messages : 82
    Points : 61
    Points
    61
    Par défaut
    Citation Envoyé par fxrobin Voir le message
    De rien, mais ça m'embête de t'avoir donné une solution à une approche "pas propre"
    Au contraire, tu m'a appris une chose très intéressante, que je l'aurai appris le jour où ils m'aurons viré :p ,
    Enfin, sur le fond, la méthode est mauvaise, car si tu es en mode "application" web (avec plusieurs clients potentiels) il est tout à fait probable que l'ID que tu récupères à un instant T pour en faire un auto-incrément rentre en concurrence avec un autre thread et donc tu auras un problème d'ID. Ne sous-estime pas cette possibilité de concurrence, elle commence à être élevée à partir d'une vingtaine d'utilisateurs.
    mais par contre je voulais savoir la solution et passé au solutions que vous m'aviez proposé toi et tchize_ comme ça je toucherai à tout

    Citation Envoyé par tchize_ Voir le message
    Déjà donné:

    http://www.developpez.net/forums/d12...d/#post6988992


    JE te donne ça demain, je fais toujours un copier coller du même code au boulot, vu le nombre monumental de fois par an où je dois créer des nouvelles tables avec trigger
    Un grand merci tchize, j'attendrai ta réponse

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Bon, voilà le code que j'utilise en général. c'est de l'extraction automatique d'oracle donc c'est inutilement verbeux sur pas mal de choses (j'ai coupé le plus gros des crasses)


    Code sql : 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
    CREATE TABLE "RH_GRADE"
      (
        "GRADE_ID" NUMBER(*,0) CONSTRAINT "PK_RH_GRADES" NOT NULL ENABLE,
        "NAME_FR"  VARCHAR2(255 CHAR),
        "NAME_NL"  VARCHAR2(255 CHAR),
        "GLEVEL"   VARCHAR2(1 CHAR),
        "ACTIVE"   VARCHAR2(1 CHAR),
        "PCODE"    VARCHAR2(10 CHAR),
        PRIMARY KEY ("GRADE_ID") 
      );
    CREATE OR REPLACE TRIGGER "RH_GRADE_ID_TRIG" BEFORE
      INSERT ON RH_GRADE REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW BEGIN
      SELECT NVL(:new.GRADE_Id,RH_GENERIC_SEQ.nextval) INTO :NEW.GRADE_Id FROM DUAL;
    END;
    /
    ALTER TRIGGER "RH_GRADE_ID_TRIG" ENABLE;
    CREATE SEQUENCE "RH_GENERIC_SEQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 66363 CACHE 20 NOORDER NOCYCLE ;

    Et le mapping hibernate correspondant

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <class name="com.company.rh.Grade" table="RH_GRADE">
      <cache usage="read-write"/>
      <id name="id">
       <column name="GRADE_ID" not-null="true" unique="true" /> <!-- ok -->
    	<generator class="sequence">
    		<param name="sequence">RH_GENERIC_SEQ</param>
    	</generator>
      </id>
     
    	<property name="nameFr" column="Name_FR" type="string"/> <!-- ok -->
    	<property name="nameNl" column="Name_NL" type="string"/> <!-- ok -->
    	<property name="pdata" column="PCode" type="string"/> <!-- ok -->
    	<property name="level" column="GLEVEL" type="string"/> <!-- ok -->
    	<property name="active" column="ACTIVE" type="yes_no"/> <!-- ok -->
     </class>

  15. #15
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    82
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2012
    Messages : 82
    Points : 61
    Points
    61
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Bon, voilà le code que j'utilise en général. c'est de l'extraction automatique d'oracle donc c'est inutilement verbeux sur pas mal de choses (j'ai coupé le plus gros des crasses)
    Thanks a lot tchize_

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

Discussions similaires

  1. [XL-2003] Récupérer le max d'une colonne
    Par Aetycc dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 13/03/2015, 04h51
  2. [MySQL] Récupérer ID MAX
    Par airsoft28 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 13/12/2012, 20h02
  3. Réponses: 1
    Dernier message: 15/08/2010, 16h03
  4. Réponses: 10
    Dernier message: 19/08/2008, 09h10
  5. [XPath] Récupérer l'ID max dans un fichier XML
    Par Phach dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 28/07/2005, 13h57

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