Précédent   Forum du club des développeurs et IT Pro > Java > Développement Web en Java
Développement Web en Java Forum d'entraide sur les technologies Web de Java (JSP/Servlets, Portlets, Applets, frameworks Web, etc.) Avant de poster -> FAQ Java EE
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 19/11/2012, 17h32   #1
xoftob
Membre à l'essai
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 48
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 : 48
Points : 21
Points : 21
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 :
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 :
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 :
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
xoftob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2012, 17h36   #2
fxrobin
Membre Expert
 
Avatar de fxrobin
 
Homme
Formateur JAVA / XML
Inscription : novembre 2007
Messages : 849
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Formateur JAVA / XML
Secteur : Service public

Informations forums :
Inscription : novembre 2007
Messages : 849
Points : 1 294
Points : 1 294
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 ...
fxrobin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2012, 17h53   #3
xoftob
Membre à l'essai
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 48
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 : 48
Points : 21
Points : 21
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 :
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
xoftob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2012, 21h04   #4
fxrobin
Membre Expert
 
Avatar de fxrobin
 
Homme
Formateur JAVA / XML
Inscription : novembre 2007
Messages : 849
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Formateur JAVA / XML
Secteur : Service public

Informations forums :
Inscription : novembre 2007
Messages : 849
Points : 1 294
Points : 1 294
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 ...
fxrobin est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/11/2012, 10h00   #5
tchize_
Expert Confirmé Sénior
 
Avatar de tchize_
 
Homme
Responsable de service informatique
Inscription : avril 2007
Messages : 18 284
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 33
Localisation : Belgique

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Service public

Informations forums :
Inscription : avril 2007
Messages : 18 284
Points : 32 759
Points : 32 759
Envoyer un message via MSN à tchize_ Envoyer un message via Skype™ à tchize_
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 :
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;
__________________
⥀⥁ Чиз faq java, cours java, javadoc. Pensez à et
Laisse entrer le jour après une nuit sombre. Si tu es toujours là, tu n'es pas faite pour mourir.
tchize_ est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/11/2012, 11h35   #6
xoftob
Membre à l'essai
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 48
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 : 48
Points : 21
Points : 21
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
Citation:
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 :
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:
Citation:
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 :
Client c = (Client) session.createQuery("select max(id) from Client").uniqueResult();
Merci
xoftob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 12h05   #7
tchize_
Expert Confirmé Sénior
 
Avatar de tchize_
 
Homme
Responsable de service informatique
Inscription : avril 2007
Messages : 18 284
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 33
Localisation : Belgique

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Service public

Informations forums :
Inscription : avril 2007
Messages : 18 284
Points : 32 759
Points : 32 759
Envoyer un message via MSN à tchize_ Envoyer un message via Skype™ à tchize_
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
__________________
⥀⥁ Чиз faq java, cours java, javadoc. Pensez à et
Laisse entrer le jour après une nuit sombre. Si tu es toujours là, tu n'es pas faite pour mourir.
tchize_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 12h43   #8
fxrobin
Membre Expert
 
Avatar de fxrobin
 
Homme
Formateur JAVA / XML
Inscription : novembre 2007
Messages : 849
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Formateur JAVA / XML
Secteur : Service public

Informations forums :
Inscription : novembre 2007
Messages : 849
Points : 1 294
Points : 1 294
Citation:
Envoyé par xoftob Voir le message
Jai ajouter le "uniqueResult" et ça me donne toujours la même erreur:

Code :
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 :
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 ...
fxrobin est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/11/2012, 16h50   #9
xoftob
Membre à l'essai
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 48
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 : 48
Points : 21
Points : 21
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 :
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
xoftob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 17h10   #10
xoftob
Membre à l'essai
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 48
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 : 48
Points : 21
Points : 21
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

Citation:
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 :
1
2
3
4
5
CREATE TRIGGER PR_ID_CLIENT
BEFORE INSERT 
ON CLIENT
UPDATE NEW 
SET ID = ID + 1
Merci beaucoup tchize
xoftob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 17h31   #11
fxrobin
Membre Expert
 
Avatar de fxrobin
 
Homme
Formateur JAVA / XML
Inscription : novembre 2007
Messages : 849
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Formateur JAVA / XML
Secteur : Service public

Informations forums :
Inscription : novembre 2007
Messages : 849
Points : 1 294
Points : 1 294
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 ...
fxrobin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 18h33   #12
tchize_
Expert Confirmé Sénior
 
Avatar de tchize_
 
Homme
Responsable de service informatique
Inscription : avril 2007
Messages : 18 284
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 33
Localisation : Belgique

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Service public

Informations forums :
Inscription : avril 2007
Messages : 18 284
Points : 32 759
Points : 32 759
Envoyer un message via MSN à tchize_ Envoyer un message via Skype™ à tchize_
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

Citation:
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
__________________
⥀⥁ Чиз faq java, cours java, javadoc. Pensez à et
Laisse entrer le jour après une nuit sombre. Si tu es toujours là, tu n'es pas faite pour mourir.
tchize_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2012, 18h51   #13
xoftob
Membre à l'essai
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 48
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 : 48
Points : 21
Points : 21
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 ,
Citation:
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
xoftob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2012, 17h27   #14
tchize_
Expert Confirmé Sénior
 
Avatar de tchize_
 
Homme
Responsable de service informatique
Inscription : avril 2007
Messages : 18 284
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 33
Localisation : Belgique

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Service public

Informations forums :
Inscription : avril 2007
Messages : 18 284
Points : 32 759
Points : 32 759
Envoyer un message via MSN à tchize_ Envoyer un message via Skype™ à tchize_
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 :
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 :
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>
__________________
⥀⥁ Чиз faq java, cours java, javadoc. Pensez à et
Laisse entrer le jour après une nuit sombre. Si tu es toujours là, tu n'es pas faite pour mourir.
tchize_ est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/11/2012, 19h03   #15
xoftob
Membre à l'essai
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 48
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 : 48
Points : 21
Points : 21
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_
xoftob est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 04h41.


 
 
 
 
Partenaires

Hébergement Web