EJB : Problème méthode findAll() avec Jonas 4.7.4 [Résolu]

mixouille 9 Messages postés jeudi 27 juillet 2006Date d'inscription 3 décembre 2015 Dernière intervention - 27 juil. 2006 à 11:35 - Dernière réponse : mixouille 9 Messages postés jeudi 27 juillet 2006Date d'inscription 3 décembre 2015 Dernière intervention
- 28 juil. 2006 à 14:02
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 :

<!-- Entity Beans -->
<entity id="ContainerManagedEntity_TestCmp">
   <description><![CDATA[<!-- begin-xdoclet-definition -->]]></description>

   <ejb-name>TestCmp</ejb-name>

   <home>com.sicc.cmp.TestCmpHome</home>
   <remote>com.sicc.cmp.TestCmp</remote>
   <local-home>com.sicc.cmp.TestCmpLocalHome</local-home>
   <local>com.sicc.cmp.TestCmpLocal</local>

   <ejb-class>com.sicc.cmp.TestCmpCMP</ejb-class>
   Container

   java.lang.Integer

   <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);
         
        } catch (Exception e) {
          System.err.println( "Impossible de trouver TestCmpHome : " + e);
          System.exit(2);
        }

        // 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;
        
        try {
            lstTrt = home.findAll();
            if (lstTrt.size() > 0) {
                Iterator iter = lstTrt.iterator();
                myTestCmp = (TestCmp)iter.next();
                returnString = myTestCmp.getTrt_libelle();
            } else {
                returnString = "RIEN";
            }
            

          Log.ajouter(Log.NIVEAU_DEBUG, NOM_PACKAGE, NOM_CLASSE, NOM_METHODE, returnString);

        } 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.

Merci beaucoup d'avance !
Afficher la suite 

Votre réponse

7 réponses

Meilleure réponse
mixouille 9 Messages postés jeudi 27 juillet 2006Date d'inscription 3 décembre 2015 Dernière intervention - 28 juil. 2006 à 14:02
3
Merci
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.

Merci mixouille 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 83 internautes ce mois-ci

Commenter la réponse de mixouille
super_toinou 764 Messages postés mardi 25 mai 2004Date d'inscription 8 mars 2011 Dernière intervention - 27 juil. 2006 à 12:12
0
Merci
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
Commenter la réponse de super_toinou
mixouille 9 Messages postés jeudi 27 juillet 2006Date d'inscription 3 décembre 2015 Dernière intervention - 27 juil. 2006 à 15:49
0
Merci
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.

Quelqu'un a-t-il d'autres idées ?
Commenter la réponse de mixouille
super_toinou 764 Messages postés mardi 25 mai 2004Date d'inscription 8 mars 2011 Dernière intervention - 27 juil. 2006 à 17:12
0
Merci
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
Commenter la réponse de super_toinou
mixouille 9 Messages postés jeudi 27 juillet 2006Date d'inscription 3 décembre 2015 Dernière intervention - 28 juil. 2006 à 09:39
0
Merci
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 ?
Commenter la réponse de mixouille
super_toinou 764 Messages postés mardi 25 mai 2004Date d'inscription 8 mars 2011 Dernière intervention - 28 juil. 2006 à 10:37
0
Merci
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
Commenter la réponse de super_toinou
mixouille 9 Messages postés jeudi 27 juillet 2006Date d'inscription 3 décembre 2015 Dernière intervention - 28 juil. 2006 à 14:01
0
Merci
Merci Toinou pour ton aide, mais j'ai réussi à trouver tout ce que je cherchais. Voir le message suivant de clôture du problème.
Commenter la réponse de mixouille

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.