J'ai un problème pour utiliser la méthode findAll() d'un EJB entité (CMP), et d'ailleurs également pour toute méthode finder personnalisée. Je tiens à préciser tout de suite que je suis débutant en matière d'EJB.
J'utilise Jonas 4.7.4 comme serveur, Oracle 9i comme base de données, et XDoclet 1.2.3 pour la génération du code.
<reentrant>false</reentrant>
<cmp-version>2.x</cmp-version>
TestCmpSCHEMA
<cmp-field id="CMPAttribute_1">
<description><![CDATA[<!-- begin-user-doc --> CMP Field id_trt Returns the id_trt]]></description>
<field-name>id_trt</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_2">
<description><![CDATA[<!-- begin-user-doc --> CMP Field trt_libelle Returns the trt_libelle]]></description>
<field-name>trt_libelle</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_3">
<description><![CDATA[<!-- begin-user-doc --> CMP Field trt_classe Returns the trt_classe]]></description>
<field-name>trt_classe</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_4">
<description><![CDATA[<!-- begin-user-doc --> CMP Field trt_creepar Returns the trt_creepar]]></description>
<field-name>trt_creepar</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_5">
<description><![CDATA[<!-- begin-user-doc --> CMP Field trt_modifpar Returns the trt_modifpar]]></description>
<field-name>trt_modifpar</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_6">
<description><![CDATA[<!-- begin-user-doc --> CMP Field trt_dtcreation Returns the trt_dtcreation]]></description>
<field-name>trt_dtcreation</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_7">
<description><![CDATA[<!-- begin-user-doc --> CMP Field trt_dtmodif Returns the trt_dtmodif]]></description>
<field-name>trt_dtmodif</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_8">
<description><![CDATA[<!-- begin-user-doc --> CMP Field trt_actif Returns the trt_actif]]></description>
<field-name>trt_actif</field-name>
</cmp-field>
id_trt
<query>
<query-method>
<method-name>findAll</method-name>
<method-params>
</method-params>
</query-method>
<ejb-ql><![CDATA[SELECT OBJECT(a) FROM TestCmpSCHEMA as a]]></ejb-ql>
</query>
<!-- Write a file named ejb-finders-TestCmpBean.xml if you want to define extra finders. -->
</entity>
Lorsque je veux appeler cette méthode, par un code du style :
// Récupération d'une référence à l'interface locale
TestCmpHome home = null;
try {
home = (TestCmpHome)PortableRemoteObject.narrow(initialContext.lookup("TestCmp"), TestCmpHome.class);
// Création d'un objet de même type que l'interafce distante
// et appel de la fonction sayHello()
TestCmp myTestCmp = null;
String returnString = "";
Collection lstTrt = null;
} catch (Exception e) {
System.err.println("Impossible de créer le bean : " + e);
System.exit(2);
}
mon serveur Jonas tombe, et j'obtiens les messages d'erreur suivants :
2006-07-26 17:56:13,671 : JOnASTestCmp2046519629Bean.ejbfindAll : Problem during the evaluation of findAll
Nested Exception
Nested Exception
java.sql.SQLException: ORA-00933: SQL command not properly ended
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:305)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:272)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:623)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:181)
at oracle.jdbc.driver.T4CPreparedStatement.execute_for_describe(T4CPreparedStatement.java:420)
at oracle.jdbc.driver.OracleStatement.execute_maybe_describe(OracleStatement.java:896)
at oracle.jdbc.driver.T4CPreparedStatement.execute_maybe_describe(T4CPreparedStatement.java:452)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:986)
at oracle.jdbc.driver.OracleStatement.doScrollExecuteCommon(OracleStatement.java:3763)
at oracle.jdbc.driver.OraclePreparedStatement.doScrollPstmtExecuteUpdate(OraclePreparedStatement.java:8829)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:2886)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:2929)
at org.objectweb.jonas.dbm.JStatement.executeQuery(JStatement.java:335)
at org.objectweb.medor.datasource.rdb.lib.JDBCWrapper.fetchData(JDBCWrapper.java:158)
at org.objectweb.medor.eval.lib.MedorEvaluator.evaluate(MedorEvaluator.java:145)
at org.objectweb.jonas_ejb.container.jorm.MedorFactory.evaluate(MedorFactory.java:245)
at org.objectweb.jonas_gen.com.sicc.cmp.JOnASTestCmp2046519629Bean.ejbfindAll(JOnASTestCmp2046519629Bean.java:557)
at org.objectweb.jonas_gen.com.sicc.cmp.JOnASTestCmp2046519629Home.findAll(JOnASTestCmp2046519629Home.java:332)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at org.objectweb.carol.rmi.jrmp.server.JUnicastServerRef.dispatch(JUnicastServerRef.java:143)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:534)
2006-07-26 17:56:13,671 : JStatement.forceClose : Statements should be closed explicitly.
Impossible de créer le bean : javax.ejb.FinderException: An error occured during the evaluation of the findAll request:Nested Exception
Je précise pour finir que je n'ai en revanche aucun problème pour utiliser un findByPrimaryKey().
Quelqu'un a-t-il idée de l'origine du problème ? J'ai cherché dans tous les sens sur le net, mais je ne trouve pas de problème semblable.
Ca y est, j'ai trouvé les réponses à toutes mes questions !
Premièrement, pour logger les requêtes sql émises par Jonas, il existe l'excellent outil p6spy, qui, en plus, est livré avec la version 4.7.4 (et probablement d'autres) de Jonas.
La configuration est très simple et expliquée ici : [url]http://www.p6spy.com/documentation/install.htm/url
Grâce à cet outil, j'ai pu voir la requête problématique générée :
SELECT SICC_ADMIN.TS_WF_TRAITETEMPO_0.ID_TRT FROM SICC_ADMIN.TS_WF_TRAITETEMPO SICC_ADMIN.TS_WF_TRAITETEMPO_0
Vous voyez le problème ? En fait Jonas ne voit visiblement pas que "SICC_ADMIN" est le schéma de la table, et préfixe donc l'alias TS_WF_TRAITETEMPO_0 avec, ce qui est évidemment interdit. La requête devrait être :
SELECT TS_WF_TRAITETEMPO_0.ID_TRT FROM SICC_ADMIN.TS_WF_TRAITETEMPO TS_WF_TRAITETEMPO_0
Pour régler le problème, j'ai trouvé 2 solutions, dans XDoclet :
1 - Dans la classe BiduleBean.java, supprimer le schéma dans les commentaires suivants :
* @ejb.persistence
* table-name="SICC_ADMIN.TS_WF_TRAITETEMPO"
* @jonas.jdbc-mapping jndi-name="DefaultDS" automatic-pk="false" jdbc-table-name="TS_WF_TRAITETEMPO"
Puis relancer XDoclet. Les classes et descripteurs sont regénérés correctement.
2 - Si, comme moi, vous utilisez l'assistant XDoclet de création d'EJB CMP dans Eclipse, lors de l'étape de sélection de la table et des champs, supprimez le schéma dans le nom de la table avant de valider l'étape.
Voilà, j'espère que cette explication aidera ceux qui seront comme moi confrontés à ce bug (parce que ca ressemble à un bug, quand même) de Jonas.
c est ta query qui ne va pas, j suis pas bon la dedans mais elle ne doit pas etre bien déclarée (ca se fini pas avec un ; ??)
SQL command not properly ended
Merci pour ta réponse super_toinou. Même si ce n'est pas particulièrement ton domaine, toute idée est la bienvenue.
J'ai essyé avec un ";", aucun changement (ou plutôt si : erreur à la fabrication du jar, et erreur au démarrage de Jonas si j'ajoute le ";" directement dans le jar généré).
J'ai consulté les tutoriaux que j'ai pu trouver sur le net, ma requête semble tout à fait conforme.
De plus, on m'a proposé de virer les CDATA autour de la requête, mais ça ne change absolument rien.
disons que j ai fait un peu d ejb sous jonas qui plus est mais quand on t a une erreur du genre SQL command not properly ended ca vient pour moi de ta requete mais au fait ton dernier a de ta requete il manque pas un where ou un truc dans le genre parce que SELECT OBJECT(a) FROM TestCmpSCHEMA as a pour moi ca veut pas dire qd chose.... genre where ou d autre trucs ???
essaye de tester ta requete sous un éditeur sql sur ta base pour voir si ca plante
++ Toinou
Vous n’avez pas trouvé la réponse que vous recherchez ?
Non, ma requête, d'après mes recherches sur le net, est bien construite et est classique d'une méthode findAll(). C'est normal que je n'ai pas de WHERE, vu que je veux tous les enregistrements de la table. D'ailleurs, j'ai aussi essayé avec une clause WHERE, du genre "where id_trt > 0", mais ca ne change rien.
Je peux pas tester ca dans un éditeur sql, vu que c'est de l'EJB-QL, seulement interprétable par les conteneurs d'EJB (je n'ai pas trouvé d'éditeur d'EJB-QL jusqu'ici).
Je suis bien d'accord avec toi quand tu dis qu'il doit y avoir un problème dans la requête SQL générée par le conteneur, le problème c'est que je ne connais pas cette requête. En effet, je n'ai pour l'instant pas trouvé de moyen de logger les requêtes générées par Jonas, et je n'ai pas la possibilité de bidouiller la base de données que j'attaque pour voir les requêtes reçues.
Quelqu'un sait-il comment faire pour que Jonas logge les requêtes SQL qu'il envoie ?
j pense que jonas utilise LOG4J, il faudrai que tu mette un niveau debug sur les classes pour voir les requetes je pense
mais ca m a bien l air bizar ton histoire, j peux pas trop t aider + que ca sorry
courage !
toinou