-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: [AIDE] : Hibernate et les requêtes natives
PostPosted: Mon Jul 18, 2005 4:21 am 
Regular
Regular

Joined: Sat May 15, 2004 4:27 am
Posts: 79
Bonjour,

j'utilise la version 2.16 d'hibernate. Jboss et Oracle. Dans le but d'optimiser
une requête couteuse, je dois la passer en native. Avant de travailler sur la
requête elle même, je suis en train de faire un test sur une requête simple.
Voici mon test :

try {
session.beginSessionStandalone();
session.beginTransaction();

StringBuffer reqNative = new StringBuffer("SELECT {typfic}.NOM AS {typfic.nom} ");
reqNative.append("FROM TYPE_FICHIER {typfic} ");

List l = session.getSession().createSQLQuery(reqNative.toString(),
"typfic", TypeFichier.class)
int len = l.size();
System.out.println("Nbre de taches : " + len);
catch (HibernateException e) {
e.printStackTrace();
}
finally {
session.endTransaction();
session.endSession();
}

Voici l'exception que j'ai :

Hibernate: SELECT typfic.NOM AS nom0_ FROM TYPE_FICHIER typfic
- SQL Error: 17006, SQLState: null
- Nom de colonne non valide
- SQL Error: 17006, SQLState: null
- Nom de colonne non valide
- SQLException occurred
java.sql.SQLException: Nom de colonne non valide
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)
at oracle.jdbc.driver.OracleStatement.get_column_index(OracleStatement.java:5971)
at oracle.jdbc.driver.OracleResultSetImpl.findColumn(OracleResultSetImpl.java:1527)
at oracle.jdbc.driver.OracleResultSet.getLong(OracleResultSet.java:1540)
at net.sf.hibernate.type.LongType.get(LongType.java:18)
at net.sf.hibernate.type.NullableType.nullSafeGet(NullableType.java:62)
at net.sf.hibernate.type.NullableType.nullSafeGet(NullableType.java:53)
at net.sf.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:427)
at net.sf.hibernate.loader.Loader.getRowFromResultSet(Loader.java:200)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:281)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133)
at net.sf.hibernate.loader.Loader.doList(Loader.java:1033)
at net.sf.hibernate.loader.Loader.list(Loader.java:1024)
at net.sf.hibernate.loader.SQLLoader.list(SQLLoader.java:92)
at net.sf.hibernate.impl.SessionImpl.findBySQL(SessionImpl.java:3806)
at net.sf.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:52)
at fr.gouv.finances.copernic.mas.stf.test.hibernate.RequeteNativeTest.main(RequeteNativeTest.java:56)
net.sf.hibernate.JDBCException: SQLException occurred
at net.sf.hibernate.impl.SessionImpl.findBySQL(SessionImpl.java:3809)
at net.sf.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:52)
at fr.gouv.finances.copernic.mas.stf.test.hibernate.RequeteNativeTest.main(RequeteNativeTest.java:56)
Caused by: java.sql.SQLException: Nom de colonne non valide
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)
at oracle.jdbc.driver.OracleStatement.get_column_index(OracleStatement.java:5971)
at oracle.jdbc.driver.OracleResultSetImpl.findColumn(OracleResultSetImpl.java:1527)
at oracle.jdbc.driver.OracleResultSet.getLong(OracleResultSet.java:1540)
at net.sf.hibernate.type.LongType.get(LongType.java:18)
at net.sf.hibernate.type.NullableType.nullSafeGet(NullableType.java:62)
at net.sf.hibernate.type.NullableType.nullSafeGet(NullableType.java:53)
at net.sf.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:427)
at net.sf.hibernate.loader.Loader.getRowFromResultSet(Loader.java:200)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:281)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133)
at net.sf.hibernate.loader.Loader.doList(Loader.java:1033)
at net.sf.hibernate.loader.Loader.list(Loader.java:1024)
at net.sf.hibernate.loader.SQLLoader.list(SQLLoader.java:92)
at net.sf.hibernate.impl.SessionImpl.findBySQL(SessionImpl.java:3806)
... 2 more

1) Qui peut me dire pourquoi ma requête ne marche pas ?

2) A terme, la requête que je dois implémenter utiliser 8 tables dans la clause FROM. Dans ce cas de figure, quelle sera la classe persistente retournée ?

3) Dans une requête native met-il possible d'utiliser toute les clauses SQL comme par exemple 'UNION ALL' ?

Merci

------
Seb


Top
 Profile  
 
 Post subject: Re: [AIDE] : Hibernate et les requêtes natives
PostPosted: Mon Jul 18, 2005 6:11 am 
Regular
Regular

Joined: Tue May 03, 2005 8:19 am
Posts: 53
Location: Paris
smayemba wrote:
Bonjour,
1) Qui peut me dire pourquoi ma requête ne marche pas ?

2) A terme, la requête que je dois implémenter utiliser 8 tables dans la clause FROM. Dans ce cas de figure, quelle sera la classe persistente retournée ?

3) Dans une requête native met-il possible d'utiliser toute les clauses SQL comme par exemple 'UNION ALL' ?

1) TYPE_FICHIER.NOM n'existe pas!, essaye ta requête dans sqlplus.
2) c'est à toi de dire quel vont être les mappings, la classe retournée devrai être ta classe mére dans ton mapping (à vérifier)
3) Toutes les commandes que ton driver JDBC accepte peuvent être utiliser


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 18, 2005 7:13 am 
Regular
Regular

Joined: Sat May 15, 2004 4:27 am
Posts: 79
> 1) TYPE_FICHIER.NOM n'existe pas!, essaye ta requête dans sqlplus.
Si le champs NOM existe bien dans la table FICHIER. La requête dans le
message d'erreur a été testé sous Toad :

SELECT typfic.NOM AS nom0_ FROM TYPE_FICHIER typfic

Elle fonctionne et me ramène bien le resultat attendu.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 18, 2005 9:52 am 
Regular
Regular

Joined: Tue May 03, 2005 8:19 am
Posts: 53
Location: Paris
Quel est le type de ce champ NOM dans le SGBD ? un varchar2?
Dans le mapping hibernate ? un long !

Parce que d'après ta stackTrace c'est un long :
at oracle.jdbc.driver.OracleResultSet.getLong(OracleResultSet.java:1540)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 19, 2005 12:38 pm 
Regular
Regular

Joined: Sat May 15, 2004 4:27 am
Posts: 79
C'est un varchar2 et un pas un Long


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 1:43 am 
Regular
Regular

Joined: Tue May 03, 2005 8:19 am
Posts: 53
Location: Paris
On est donc d'accord qu'en base de donnée tu as un varchar2,
mais le paramétrage de ton mapping hibernate quel est il ?
moi d'après ta stackTrace je pense à un long, mais ...

Code:
at oracle.jdbc.driver.OracleResultSet.getLong(OracleResultSet.java:1540)
at net.sf.hibernate.type.LongType.get(LongType.java:18)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 20, 2005 6:00 am 
Regular
Regular

Joined: Sat May 15, 2004 4:27 am
Posts: 79
Je te remercie lauvigne. J'ai résolu mon prb. La requête que je voulais faire
en native fonctionne. Pour les curieux, la voici :

StringBuffer reqRechTaches = new StringBuffer("SELECT {tache.*}, {agent.*}, {agentParAutomate.*}, {transfert.*} , {fichier.*}, {machine.*} ");
reqRechTaches.append("FROM TACHE_ELEMENTAIRE {tache}, AGENT {agent}, AGENT_PAR_AUTOMATE {agentParAutomate}, TRANSFERT {transfert}, ");
reqRechTaches.append("FICHIER {fichier}, MACHINE {machine} ");
reqRechTaches.append("WHERE (({tache}.agent_id_fk = {agent}.agent_id) AND ({agent}.agent_id = {agentParAutomate}.agent_id_fk) AND ");
reqRechTaches.append("({transfert}.transfert_id = {tache}.transfert_id_fk) AND ({tache}.fichier_id_fk = {fichier}.fichier_id) AND ");
reqRechTaches.append("({agent}.machine_id_fk = {machine}.machine_id)) ");
reqRechTaches.append("AND {transfert}.statut_id_fk NOT IN (5, 6, 7, 8) ");
reqRechTaches.append("AND {tache}.statut_id_fk NOT IN (5, 6, 7, 8) ");
reqRechTaches.append("AND {agentParAutomate}.automate_id_fk = :automateId ");
reqRechTaches.append("AND {transfert}.date_declenchement < SYSDATE ");
reqRechTaches.append("AND ({tache}.date_debut_planifiee IS NULL OR {tache}.date_debut_planifiee < SYSDATE) ");
reqRechTaches.append("AND ({agent}.demarre = 1) AND ({agent}.actif = 1) ");
reqRechTaches.append("AND NOT EXISTS ");
reqRechTaches.append(" (SELECT NULL from Predecesseur PR1 WHERE PR1.tache_elementaire_id_fk = {tache}.tache_elementaire_id) ");
reqRechTaches.append("UNION ALL ");
reqRechTaches.append("SELECT {tache.*}, {agent.*}, {agentParAutomate.*}, {transfert.*} , {fichier.*}, {machine.*} ");
reqRechTaches.append("FROM TACHE_ELEMENTAIRE {tache}, AGENT {agent}, AGENT_PAR_AUTOMATE {agentParAutomate}, TRANSFERT {transfert}, ");
reqRechTaches.append("FICHIER {fichier}, MACHINE {machine} ");
reqRechTaches.append("WHERE (({tache}.agent_id_fk = {agent}.agent_id) AND ({agent}.agent_id = {agentParAutomate}.agent_id_fk) AND ");
reqRechTaches.append("({transfert}.transfert_id = {tache}.transfert_id_fk) AND ({tache}.fichier_id_fk = {fichier}.fichier_id) AND ");
reqRechTaches.append("({agent}.machine_id_fk = {machine}.machine_id)) ");
reqRechTaches.append("AND {transfert}.statut_id_fk NOT IN (5, 6, 7, 8) ");
reqRechTaches.append("AND {tache}.statut_id_fk NOT IN (5, 6, 7, 8) ");
reqRechTaches.append("AND {agentParAutomate}.automate_id_fk = :automateId ");
reqRechTaches.append("AND {transfert}.date_declenchement < SYSDATE ");
reqRechTaches.append("AND ({tache}.date_debut_planifiee IS NULL OR {tache}.date_debut_planifiee < SYSDATE) ");
reqRechTaches.append("AND ({agent}.demarre = 1) AND ({agent}.actif = 1) ");
reqRechTaches.append("AND {tache}.tache_elementaire_id IN ( ");
reqRechTaches.append(" SELECT PR2.tache_elementaire_id_fk ");
reqRechTaches.append(" FROM tache_elementaire TA3, Predecesseur PR2 ");
reqRechTaches.append(" WHERE (PR2.predecesseur_id = TA3.tache_elementaire_id) AND TA3.statut_id_fk IN (7)) ");

long cputime1 = System.currentTimeMillis();

List hqlRechTaches = session.getSession().createSQLQuery(reqRechTaches.toString(),
new String[]{"tache", "agent", "agentParAutomate", "transfert", "fichier", "machine"},
new Class[]{TacheElementaire.class, AgentStf.class, AgentParAutomate.class, Transfert.class, Fichier.class,
Machine.class})
.setParameter("automateId", pNomAutomate, Hibernate.STRING)
.list();

if (sLogger.isDebugEnabled()) {
sLogger.debug("Temps REQ=/#" + (System.currentTimeMillis() - cputime1));
}

1) La requête fonctionne trés bien mais je ne pensais pas que le natif Hibernate serait aussi couteux. La requête s'execute en 4 secondes.
C'est un temps encore beaucoup trop pour mon application. A part
récupérer une connexion pour faire du FULL JDBC, qui sait comment
faire pour améliorer le temps d'éxécution de ma requête ?

2) SUr DBVisualizer elle ne mets que 0.063 sec pour s'éxécuter. Est-ce
que les secondes en plus sont dûes à la reflection (ou le traitement en
général) fait par Hibernate ?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.