9 Replies Latest reply: Jul 15, 2013 4:17 AM by martani RSS

    Force Jena Adapter to generate SQL and not SEM_MATCH calls

    martani

      Hi,

      I have the following query in which I bind ?o and ?s to some values (using ORACLE_SEM_UEAP_NS namespaces)

       

      SELECT * WHERE 
      {
          ?s    vcard:postal-code    ?o
      }
      

       

      I have two environments on which I run this query with Jena Adapter; remotely with JDeveloper and on Oracle's database JVM.

       

      When running remotely, I can see that SQL is always generated for this query; whatever binding I am using.

      When running on Oracle JVM, the first execution in the current session gets SQL generated. All subsequent queries with a modified binding (for example: initial query, only ?o is bound; second query, ?s is bound), Jena Adapater generates SEM_MATCH calls. If I execute the initial query again, SQL is generated.

       

      Is there a way to force Jena Adapter to stick to SQL rather than SEM_MATCH in this case ?

       

      Thank you.

        • 1. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
          alwu-Oracle

          Hi Martani,

           

          Could you please cut & paste below how you run that SPARQL query in Oracle's database JVM?

          I assume that you are using GraphOracleSem or DatasetGraphOracleSem from JDeveloper.

           

          Thanks,


          Zhe

          • 2. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
            martani

            Hi,

             

            I have a static method that I can run from a java program with JDeveloper, or which I can call from PL/SQL wrapper on Oracle JVM (after deploying with loadjava all jars + code necessary)

             

            public static void runQuery() {
                //Init model
                String[] modelNames = ...;
                String[] rulebases = ...;
            
                Attachment attachment = Attachment.createInstance(modelNames,
                                                        rulebases,
                                                        InferenceMaintenanceMode.NO_UPDATE,
                                                        QueryOptions.ALLOW_QUERY_INVALID_AND_DUP);
                                                     
                GraphOracleSem graph = new GraphOracleSem(_oracle , principalModelName, attachment, true);
                ModelOracleSem _model = new ModelOracleSem(graph);
            
                //Construct the query with the binding namespaces etc.
                String sparqlQuery = "...";
            
                Query query = QueryFactory.create(sparqlQuery, Syntax.syntaxSPARQL_11);
                QueryExecution qexec = QueryExecutionFactory.create(query, _model);
                ResultSet results = qexec.execSelect();
            
                //consume results
            }
            
            
            

             

            Indeed I am using GraphOracleSem, however I do not know what impact this has on the underlying generation of SQL/SEM_MATCH calls.

             

            Thank you.

             

            Update:

             

            This happens for every query actually, not necessarily one with bind variables. First query in session gets SQL generated, subsequent queries have SEM_MATCH generated.

             

            Ce message a été modifié par : martani

            • 3. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
              alwu-Oracle

              Could you provide a complete list of the jars that you loaded using loadjava?

               

              Thanks,


              Zhe Wu

              • 4. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
                martani

                These are the jars I load into Oracle

                 

                arq-2.8.8.jar         

                iri-0.8.jar          

                junit-4.5.jar         

                slf4j-log4j12-1.5.8.jar 

                xercesImpl-2.7.1.jar

                jena-2.6.4.jar       

                log4j-1.2.13.jar      

                sdordf.jar          

                stax-api-1.0.1.jar

                icu4j-3.4.4.jar       

                jena-2.6.4-tests.jar 

                lucene-core-2.3.1.jar 

                slf4j-api-1.5.8.jar 

                wstx-asl-3.2.9.jar

                 

                ODCI.jar            

                CartridgeServices.jar 

                 

                sdordfclient.jar  // Compiled for JDK 1.5

                 

                 

                Thanks.

                • 5. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
                  alwu-Oracle

                  Hi Martani,

                   

                  I loaded these jars (plus a few others to minimize the resolution warnings) into Oracle JVM and tried the following small test program. The trace showed that both queries were translated into SQL before execution.  Can you please give it a try in your environment?

                   

                    create or replace and compile 
                      java source named "rdf.Test"
                    as   
                      package rdf;
                      import java.util.*;
                      import oracle.spatial.rdf.client.jena.*;
                      import oracle.jdbc.pool.OracleDataSource;
                      import oracle.jdbc.OracleConnection;
                      import com.hp.hpl.jena.query.*;
                      import com.hp.hpl.jena.rdf.model.Model;
                      import com.hp.hpl.jena.util.FileManager;
                      import com.hp.hpl.jena.util.iterator.*;
                      import oracle.spatial.rdf.client.jena.*;
                      import com.hp.hpl.jena.graph.*;
                      import com.hp.hpl.jena.update.*;
                      public class Test 
                      {
                        public static void test() throws Exception
                        {
                          String[] modelNames = new String[]{};  
                          String[] rulebases =new String[]{};
                  
                          OracleDataSource ods = new OracleDataSource();
                          ods.setURL("jdbc:oracle:kprb");
                          OracleConnection oc = (OracleConnection) ods.getConnection();
                          Oracle oracle = new Oracle(oc);
                  
                          Attachment attachment = Attachment.createInstance(modelNames,  
                              rulebases,  
                              InferenceMaintenanceMode.NO_UPDATE,  
                              QueryOptions.ALLOW_QUERY_INVALID_AND_DUP);  
                  
                          GraphOracleSem graph = new GraphOracleSem(oracle , "in_oracle", attachment, true);  
                          ModelOracleSem model = new ModelOracleSem(graph);  
                  
                          Node sub = Node.createURI("http://sub/a");
                          Node pred = Node.createURI("http://pred/a");
                          Node obj = Node.createURI("http://obj/a");
                          Triple triple = Triple.create(sub, pred, obj);
                          graph.add(triple);
                  
                          {
                            String sparqlQuery = "select * {?s ?p ?o} limit 1";  
                            System.err.println("Test.test: before query 1");
                            Query query = QueryFactory.create(sparqlQuery, Syntax.syntaxSPARQL);  
                            QueryExecution qexec = QueryExecutionFactory.create(query, model);  
                            ResultSet results = qexec.execSelect();  
                            ResultSetFormatter.out(System.err, results, query);
                            System.err.println("Test.test: done query 1");
                          }
                  
                          {
                            String sparqlQuery = "select * {?s  ?o} limit 1";  
                            System.err.println("Test.test: before query 2");
                            Query query = QueryFactory.create(sparqlQuery, Syntax.syntaxSPARQL);  
                            QueryExecution qexec = QueryExecutionFactory.create(query, model);  
                            ResultSet results = qexec.execSelect();  
                            ResultSetFormatter.out(System.err, results, query);
                            System.err.println("Test.test: done query 2");
                          }
                  
                          model.close();
                        }
                      }
                    /
                  
                  
                  • 6. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
                    alwu-Oracle

                    Note that this Forum UI messed up the second query, which should be:

                          String sparqlQuery = "select * {?s <http://pred/a> ?o} limit 1"; 

                     

                     

                    Thanks,


                    Zhe Wu

                    • 7. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
                      martani

                      Hi,

                       

                      Thanks for your reply. I traced back the problem to this line.

                       

                      OracleConnection conn = (OracleConnection) ods.getConnection();
                      ...
                      conn.close();
                      
                      

                       

                      It appears that if I close the connection when running on Oracle, Jena Adapter generates SEM_MATCH call for subsequent queries which have a different syntax than the first one. I am curious to why is this is the case.

                       

                      Regards.

                      • 8. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
                        alwu-Oracle

                        Hi Martani,

                         

                        If I add a conn.close() between the two SPARQL queries, I get a "closed connection exception" as follows when executing the code.  It is very strange that SEM_MATCH queries can go through on a closed connection.

                         

                        SQL>  exec test;

                        BEGIN test; END;

                         

                        *

                        ERROR at line 1:

                        ORA-29532: Java call terminated by uncaught Java exception:

                        com.hp.hpl.jena.shared.JenaException: java.sql.SQLException: Closed Connection

                        ORA-06512: at "NET.TEST", line 1

                        ORA-06512: at line 1

                         

                        Now, SEM_MATCH based queries are generated because we have a fall back mechanism that acts like a safety net.

                        If S2S fails (due to closed connection in this case), we switch back to SEM_MATCH. In this case, SEM_MATCH should also fail because there is no available connection to do anything meaningful.

                         

                        Thanks,


                        Zhe Wu

                        • 9. Re: Force Jena Adapter to generate SQL and not SEM_MATCH calls
                          martani

                          Hi,

                           

                          I actually meant opening the connection, performing a query, closing the connection; then reopening it, performing the other query and then closing it again.

                          Like in the following code:

                           

                          public static void runQuery(String sparqlQuery) throws Exception
                          {
                              String[] modelNames = new String[]{}; 
                              String[] rulebases =new String[]{};
                          
                              OracleDataSource ods = new OracleDataSource();
                              ods.setURL("jdbc:oracle:kprb");
                              OracleConnection oc = (OracleConnection) ods.getConnection();
                              Oracle oracle = new Oracle(oc);
                          
                              Attachment attachment = Attachment.createInstance(modelNames, rulebases, InferenceMaintenanceMode.NO_UPDATE, QueryOptions.ALLOW_QUERY_INVALID_AND_DUP);
                          
                              GraphOracleSem graph = new GraphOracleSem(oracle , "in_oracle", attachment, true); 
                              ModelOracleSem model = new ModelOracleSem(graph); 
                          
                              Node sub = Node.createURI("http://sub/a");
                              Node pred = Node.createURI("http://pred/a");
                              Node obj = Node.createURI("http://obj/a");
                              Triple triple = Triple.create(sub, pred, obj);
                              graph.add(triple);
                          
                              System.err.println("Test.test: before query 1");
                              Query query = QueryFactory.create(sparqlQuery, Syntax.syntaxSPARQL); 
                              QueryExecution qexec = QueryExecutionFactory.create(query, model); 
                              ResultSet results = qexec.execSelect(); 
                              ResultSetFormatter.out(System.err, results, query);
                              System.err.println("Test.test: done query 1");
                             
                              model.close();
                              oc.close();     //Close the connection here
                          }
                          
                          public static void test() {
                              try {
                                  runQuery("select * {?s <http://pred/a> ?oo} limit 1");
                                  runQuery("select * {?s ?p ?oo} limit 1");
                              } catch (Exception e) {
                                  e.printStackTrace();
                              }
                          }
                          
                          

                           

                          I am getting SEM_MATCH generated for the second query.

                           

                          Thank you.