Bonjour, bonsoir,
Je suis actuellement en train de développer un site Web en JEE pour un projet scolaire. J'utilise le modèle MVC avec une couche DAO qui appelle un Service Web REST et donc une couche CRUD supplémentaire. L'interaction entre ces couches se fait parfaitement bien. Seulement, lorsque ma couche CRUD appelle ma base de données, une exception est lancée. Voici sa Stack Trace :
Voici, en Java, l'endroit où j'appelle ma fonction stockée dans la base de donnée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 2017-12-28T19:40:12.533+0100|Grave: java.sql.SQLException: Parametre IN ou OUT absent dans l'index :: 1 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:1887) at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3409) at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3520) at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4611) at be.gestionhopital.CRUD.ChirurgienCRUD.getChirurgiens(ChirurgienCRUD.java:43) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:309) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) at org.glassfish.jersey.internal.Errors.process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:267) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:292) at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1139) at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:460) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:334) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283) at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) at java.lang.Thread.run(Thread.java:748)
Et voici la fonction stockée dans un package PL/SQL :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 @GET @Produces(MediaType.TEXT_XML) public Response getChirurgiens() throws SQLException { CallableStatement getChir = null; ResultSet results = null; ResultSet obj = null; int i = 0; String retour = "<?xml version=\"1.0\"?>"; retour += "<listeChirurgiens>"; try{ getChir = conn.prepareCall("{ ? = call SelectAll.getChirurgiens }"); getChir.registerOutParameter(1, OracleTypes.PLSQL_INDEX_TABLE); //java.sql.SQLException: Paramètre IN ou OUT absent dans l'index :: 1 getChir.execute(); while((results = (ResultSet)getChir.getObject(1)) != null) { while((obj = (ResultSet)results.getObject(i)) != null) { while(obj.next()) { retour += "<chirurgien>"; retour += "<id>"+results.getDouble("IdPersonne")+"</id>"; retour += "<nom>"+results.getString("Nom")+"</nom>"; retour += "<prenom>"+results.getString("Prenom")+"</prenom>"; retour += "<dateNaissance>"+results.getDate("DateNaissance")+"</dateNaissance>"; retour += "<numTelephone>"+results.getString("NumeroTelephone")+"</numTelephone>"; retour += "<motDePasse>"+results.getString("MotDePasse")+"</motDePasse>"; retour += "<specialisation>"+results.getString("Specialisation")+"</specialisation>"; retour += "</chirurgien>"; } } i++; } } catch(SQLException e) { e.printStackTrace(); } finally { if(obj != null) obj.close(); if(results != null) results.close(); if(getChir != null) getChir.close(); } retour += "</listeChirurgiens>"; return Response.status(Status.OK).entity(retour).build(); }
Le tout est hébergé grâce à GlassFish.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 create or replace package SelectAll is TYPE tab_pers IS TABLE OF Personne%ROWTYPE NOT NULL INDEX BY binary_integer; row_pers tab_pers; TYPE tab_chir IS TABLE OF Chirurgien%ROWTYPE NOT NULL INDEX BY binary_integer; row_chir tab_chir; TYPE rec_chir IS RECORD (IdPersonne Personne.IdPersonne%TYPE,Nom Personne.nom%type,Prenom Personne.prenom%type,DateNaissance Personne.DateNaissance%type,NumeroTelephone Personne.NumeroTelephone%type,MotDePasse Personne.MotDePasse%type,Specialisation Chirurgien.Specialisation%type); full_chir rec_chir; TYPE tab_rec_chir IS TABLE OF rec_chir NOT NULL INDEX BY binary_integer; row_rec_chir tab_rec_chir; function getChirurgiens return tab_rec_chir; end SelectAll; create or replace package body SelectAll is function getChirurgiens return tab_rec_chir as begin select * bulk collect into row_chir from Chirurgien; FOR x IN 1..row_chir.count LOOP select * bulk collect into row_pers from Personne where IdPersonne = row_chir(x).IdPersonne; row_rec_chir(x).IdPersonne := row_pers(1).IdPersonne; row_rec_chir(x).Nom := row_pers(1).Nom; row_rec_chir(x).Prenom := row_pers(1).Prenom; row_rec_chir(x).DateNaissance := row_pers(1).DateNaissance; row_rec_chir(x).NumeroTelephone := row_pers(1).NumeroTelephone; row_rec_chir(x).MotDePasse := row_pers(1).MotDePasse; row_rec_chir(x).Specialisation := row_chir(x).Specialisation; END LOOP; RETURN row_rec_chir; end getChirurgiens; end SelectAll;
J'essaye de récupérer une TABLE de RECORD en PL/SQL depuis mon Java. C'est pour cela que le type se trouvant dans registerOutParameter est OracleTypes.PLSQL_INDEX_TABLE. C'est le seul type qui fonctionne. Néanmoins, il me lance cette exception. J'ai fait énormément de recherche et j'ai trouvé une solution possible : Utiliser des OBJECT en PL/SQL. Mais je ne sais pas si je peux y stocker plusieurs lignes de mon SELECT comme avec une TABLE (grâce au BULK COLLECT) et de plus, nous n'avons pas vu ces OBJECT en cours. J'aimerais donc ne pas devoir les utiliser.
Celui ou celle qui trouvera la solution sera mon héros/héroïne ^^
Merci d'avance.
Partager