[RESOLU] EJB : Problème méthode findAll() avec Jonas

EJB : Problème méthode findAll() avec Jonas [RESOLU] - Java - Programmation

Marsh Posté le 27-07-2006 à 09:48:07    

Bonjour,
 
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.
 
Voici un extrait de mon fichier ejb-jar.xml :

Code :
  1. <!-- Entity Beans -->
  2. <entity id="ContainerManagedEntity_TestCmp">
  3.    <description><![CDATA[<!-- begin-xdoclet-definition -->]]></description>
  4.    <ejb-name>TestCmp</ejb-name>
  5.    <home>com.sicc.cmp.TestCmpHome</home>
  6.    <remote>com.sicc.cmp.TestCmp</remote>
  7.    <local-home>com.sicc.cmp.TestCmpLocalHome</local-home>
  8.    <local>com.sicc.cmp.TestCmpLocal</local>
  9.    <ejb-class>com.sicc.cmp.TestCmpCMP</ejb-class>
  10.    <persistence-type>Container</persistence-type>
  11.    <prim-key-class>java.lang.Integer</prim-key-class>
  12.    <reentrant>false</reentrant>
  13.    <cmp-version>2.x</cmp-version>
  14.    <abstract-schema-name>TestCmpSCHEMA</abstract-schema-name>
  15.    <cmp-field id="CMPAttribute_1">
  16.       <description><![CDATA[<!-- begin-user-doc --> CMP Field id_trt Returns the id_trt]]></description>
  17.       <field-name>id_trt</field-name>
  18.    </cmp-field>
  19.    <cmp-field id="CMPAttribute_2">
  20.       <description><![CDATA[<!-- begin-user-doc --> CMP Field trt_libelle Returns the trt_libelle]]></description>
  21.       <field-name>trt_libelle</field-name>
  22.    </cmp-field>
  23.    <cmp-field id="CMPAttribute_3">
  24.       <description><![CDATA[<!-- begin-user-doc --> CMP Field trt_classe Returns the trt_classe]]></description>
  25.       <field-name>trt_classe</field-name>
  26.    </cmp-field>
  27.    <cmp-field id="CMPAttribute_4">
  28.       <description><![CDATA[<!-- begin-user-doc --> CMP Field trt_creepar Returns the trt_creepar]]></description>
  29.       <field-name>trt_creepar</field-name>
  30.    </cmp-field>
  31.    <cmp-field id="CMPAttribute_5">
  32.       <description><![CDATA[<!-- begin-user-doc --> CMP Field trt_modifpar Returns the trt_modifpar]]></description>
  33.       <field-name>trt_modifpar</field-name>
  34.    </cmp-field>
  35.    <cmp-field id="CMPAttribute_6">
  36.       <description><![CDATA[<!-- begin-user-doc --> CMP Field trt_dtcreation Returns the trt_dtcreation]]></description>
  37.       <field-name>trt_dtcreation</field-name>
  38.    </cmp-field>
  39.    <cmp-field id="CMPAttribute_7">
  40.       <description><![CDATA[<!-- begin-user-doc --> CMP Field trt_dtmodif Returns the trt_dtmodif]]></description>
  41.       <field-name>trt_dtmodif</field-name>
  42.    </cmp-field>
  43.    <cmp-field id="CMPAttribute_8">
  44.       <description><![CDATA[<!-- begin-user-doc --> CMP Field trt_actif Returns the trt_actif]]></description>
  45.       <field-name>trt_actif</field-name>
  46.    </cmp-field>
  47.     <primkey-field>id_trt</primkey-field>
  48.    <query>
  49.       <query-method>
  50.          <method-name>findAll</method-name>
  51.          <method-params>
  52.          </method-params>
  53.       </query-method>
  54.       <ejb-ql><![CDATA[SELECT OBJECT(a) FROM TestCmpSCHEMA as a]]></ejb-ql>
  55.       </query>
  56. <!-- Write a file named ejb-finders-TestCmpBean.xml if you want to define extra finders. -->
  57. </entity>


 
Lorsque je veux appeler cette méthode, par un code du style :

Code :
  1. // Récupération d'une référence à l'interface locale
  2.     TestCmpHome home = null;
  3.     try {
  4.       home = (TestCmpHome)PortableRemoteObject.narrow(initialContext.lookup("TestCmp" ), TestCmpHome.class);
  5.    
  6.     } catch (Exception e) {
  7.       System.err.println( "Impossible de trouver TestCmpHome : " + e);
  8.       System.exit(2);
  9.     }
  10.     // Création d'un objet de même type que l'interafce distante
  11.     // et appel de la fonction sayHello()
  12.     TestCmp myTestCmp = null;
  13.     String returnString = "";
  14.     Collection lstTrt = null;
  15.    
  16.     try {
  17.      lstTrt = home.findAll();
  18.      if (lstTrt.size() > 0) {
  19.       Iterator iter = lstTrt.iterator();
  20.       myTestCmp = (TestCmp)iter.next();
  21.       returnString = myTestCmp.getTrt_libelle();
  22.      } else {
  23.       returnString = "RIEN";
  24.      }
  25.    
  26.       Log.ajouter(Log.NIVEAU_DEBUG, NOM_PACKAGE, NOM_CLASSE, NOM_METHODE, returnString);
  27.     } catch (Exception e) {
  28.       System.err.println("Impossible de créer le bean : " + e);
  29.       System.exit(2);
  30.     }


 
mon serveur Jonas tombe, et j'obtiens les messages d'erreur suivants :

Code :
  1. 2006-07-26 17:56:13,671 : JOnASTestCmp2046519629Bean.ejbfindAll : Problem during the evaluation of findAll
  2. Nested Exception
  3. Nested Exception
  4. java.sql.SQLException: ORA-00933: SQL command not properly ended
  5. at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)
  6. at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:305)
  7. at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:272)
  8. at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:623)
  9. at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:181)
  10. at oracle.jdbc.driver.T4CPreparedStatement.execute_for_describe(T4CPreparedStatement.java:420)
  11. at oracle.jdbc.driver.OracleStatement.execute_maybe_describe(OracleStatement.java:896)
  12. at oracle.jdbc.driver.T4CPreparedStatement.execute_maybe_describe(T4CPreparedStatement.java:452)
  13. at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:986)
  14. at oracle.jdbc.driver.OracleStatement.doScrollExecuteCommon(OracleStatement.java:3763)
  15. at oracle.jdbc.driver.OraclePreparedStatement.doScrollPstmtExecuteUpdate(OraclePreparedStatement.java:8829)
  16. at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:2886)
  17. at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:2929)
  18. at org.objectweb.jonas.dbm.JStatement.executeQuery(JStatement.java:335)
  19. at org.objectweb.medor.datasource.rdb.lib.JDBCWrapper.fetchData(JDBCWrapper.java:158)
  20. at org.objectweb.medor.eval.lib.MedorEvaluator.evaluate(MedorEvaluator.java:145)
  21. at org.objectweb.jonas_ejb.container.jorm.MedorFactory.evaluate(MedorFactory.java:245)
  22. at org.objectweb.jonas_gen.com.sicc.cmp.JOnASTestCmp2046519629Bean.ejbfindAll(JOnASTestCmp2046519629Bean.java:557)
  23. at org.objectweb.jonas_gen.com.sicc.cmp.JOnASTestCmp2046519629Home.findAll(JOnASTestCmp2046519629Home.java:332)
  24. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  25. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  26. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  27. at java.lang.reflect.Method.invoke(Method.java:324)
  28. at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
  29. at org.objectweb.carol.rmi.jrmp.server.JUnicastServerRef.dispatch(JUnicastServerRef.java:143)
  30. at sun.rmi.transport.Transport$1.run(Transport.java:148)
  31. at java.security.AccessController.doPrivileged(Native Method)
  32. at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
  33. at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
  34. at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
  35. at java.lang.Thread.run(Thread.java:534)
  36. 2006-07-26 17:56:13,671 : JStatement.forceClose : Statements should be closed explicitly.
  37. 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.
 
Merci beaucoup d'avance !


Message édité par mixoumix le 28-07-2006 à 12:11:31
Reply

Marsh Posté le 27-07-2006 à 09:48:07   

Reply

Marsh Posté le 27-07-2006 à 11:34:43    

- Essaye peut-être sans le CDATA dans ton EJB-QL;
- Dans les options de ton serveur, il doit être possible de logger tous les queries SQL envoyés au RDBMS. Tu risques d'y trouver qq chose d'intéressant.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 27-07-2006 à 14:39:35    

- Pour le CDATA, j'ai essayé sans : aucun changement
- Pour le logging des requetes de Jonas, je cherche, je n'ai pas trouvé pour l'instant. Si quelqu'un sait comment faire...  :)


Message édité par mixoumix le 27-07-2006 à 14:40:09
Reply

Marsh Posté le 27-07-2006 à 15:00:58    

J'oubliais : merci, sircam, pour ta contribution, toutes les propositions sont bonnes à prendre. ;)

Reply

Marsh Posté le 27-07-2006 à 16:13:55    

Je pose donc à tous la question, fort justement suggérée par sircam :
"Quelqu'un sait-il comment logger les requêtes SQL émises par Jonas, y compris celles générées par les conteneurs EJB ?".
 
Merci, votre réponse n'est certes pas vitale, mais Ô combien attendue ;)

Reply

Marsh Posté le 27-07-2006 à 17:00:51    

Google : Jonas log jdbc ?


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 28-07-2006 à 09:26:31    

Ben non, je suis pas de ceux qui postent une question dès qu'ils ne savent pas faire quelque chose. J'ai cherché un bon moment sur le net, et j'ai pas trouvé la solution. J'ai aussi fouillé les fichiers de config de Jonas, ainsi que la console d'admin, mais, même en activant tous les logs que j'ai trouvés, les requêtes ne sont pas loggées.
Merci quand même sircam, à un moment j'ai cru que la recherche que tu m'indiquais allait me donner la réponse (un peu d'espoir, ca fait du bien), mais pour l'instant je n'ai rien trouvé de probant.
Quelqu'un d'autre sait-il comment faire ?
Sircam, tu sais faire ça avec d'autres serveurs d'application ? Comment ? Ca peut m'aider dans ma recherche.

Reply

Marsh Posté le 28-07-2006 à 11:07:47    

Tu as dû (très mal) mal chercher. 15 secondes:
 

Citation :

The P6Spy tool is integrated into JOnAS and it provides an easy way to trace the SQL requests sent to the database.


 
A défaut, il est aussi possible de logger les queries au niveau Oracle, c'est sûr et certain!


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 28-07-2006 à 12:09:38    

En effet j'avais très mal cherché (pourtant j'y avais passé du temps :( ), et j'ai trouvé entre temps. Merci sircam.
Et grâce à ca j'ai trouvé la solution à mon problème, cf. mon post suivant, qui est celui que je poste sur tous les forums que j'ai utilisés.
Merci encore sircam ! :)


Message édité par mixoumix le 28-07-2006 à 12:10:33
Reply

Marsh Posté le 28-07-2006 à 12:10:47    

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 : http://www.p6spy.com/documentation/install.htm
 
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 :

Code :
  1. *  @ejb.persistence
  2. *   table-name="SICC_ADMIN.TS_WF_TRAITETEMPO"


Code :
  1. * @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.


Message édité par mixoumix le 28-07-2006 à 12:12:14
Reply

Marsh Posté le 28-07-2006 à 12:10:47   

Reply

Marsh Posté le 28-07-2006 à 14:48:02    

Evidemment ces solutions supposent que l'on n'ait pas besoin de préciser le schéma, ce qui n'est pas toujours le cas. Je n'ai trouvé (vu que je n'ai pas trop cherché) aucune façon d'éviter le préfixage par Jonas des alias utilisés.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed