Loading and querying default and named RDF graphs in Openlink Virtuoso

760 views Asked by At

I am quite new to OpenLink Virtuoso, and I have some questions regarding loading RDF graphs and executing SPARQL queries against them through Java and Virtuoso Jena Provider.

I have installed Virtuoso version 06.01.3127 on a PC running Ubuntu 16.04 desktop edition. Also, I use Virtuoso Jena Provider 3 and Virtuoso JDBC 4 Driver.

I want to run SPARQL queries invoking both default and named graphs like the following:

prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix cc: <http://example.org/cc/>
SELECT ?c1 ?sx ?c2 ?m
FROM <http://test.org>
WHERE { ?c1 rdf:type cc:Test1; cc:p11 ?sx.
     ?c2 rdf:type cc:Test2; cc:p21 ?sx; cc:p22 ?m.
     FILTER EXISTS { GRAPH <http://testA.org> {?m cc:p cc:M.} }
}

So it is assumed that there is a default graph (http://test.org) and one named graph (http://testA.org).

I tried to use the VirtDataset as follows:

VirtModel Model1 = VirtModel.openDefaultModel("jdbc:virtuoso://localhost:1111/charset=UTF-8", <usr>, <pass>);
Model1.read(RDF1InputStream, null, "TTL");
VirtModel Model2 = VirtModel.openDatabaseModel("http://testA.org", "jdbc:virtuoso://localhost:1111/charset=UTF-8", <usr>, <pass>);
Model2.read(RDF2InputStream, null, "TTL");
VirtDataset virtDataset = new VirtDataset("jdbc:virtuoso://localhost:1111/charset=UTF-8", <usr>, <pass>);
virtDataset.setDefaultModel(Model1);
virtDataset.addNamedModel("http://testA.org", Model2);

String queryString = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
        prefix cc: <http://example.org/cc/>
        SELECT ?c1 ?sx ?c2 ?m
        WHERE { ?c1 rdf:type cc:Test1; cc:p11 ?sx.
         ?c2 rdf:type cc:Test2; cc:p21 ?sx; cc:p22 ?m.
         FILTER EXISTS { GRAPH <http://testA.org> {?m cc:p cc:M.} }
        }";
Query query = QueryFactory.create(queryString);
QueryExecution qe = QueryExecutionFactory.create(query, virtDataset);
ResultSet rs = qe.execSelect();
while (rs.hasNext()) {
    System.out.println(rs.next());
}
qe.close();
virtDataset.close();

However, it ends up with the following error in line: Model1.read(RDF1InputStream, null, "TTL");

Exception in thread "main" org.apache.jena.shared.JenaException: java.sql.BatchUpdateException: SR185: Undefined procedure DB.DBA.rdf_insert_triple_c.
    at virtuoso.jena.driver.VirtGraph.stopBatchAdd(VirtGraph.java:1090)
    at virtuoso.jena.driver.VirtModel.read(VirtModel.java:273)
    at VirtuosoTest.main(VirtuosoTest.java:45)
Caused by: java.sql.BatchUpdateException: SR185: Undefined procedure DB.DBA.rdf_insert_triple_c.
    at virtuoso.jdbc4.VirtuosoPreparedStatement.throwBatchUpdateException(VirtuosoPreparedStatement.java:520)
    at virtuoso.jdbc4.VirtuosoPreparedStatement.executeBatchUpdate(VirtuosoPreparedStatement.java:156)
    at virtuoso.jdbc4.VirtuosoPreparedStatement.executeBatch(VirtuosoPreparedStatement.java:541)
    at virtuoso.jena.driver.VirtGraph.stopBatchAdd(VirtGraph.java:1083)
    ... 2 more

Is the procedure DB.DBA.rdf_insert_triple_c missing? How can I fix this?

As an alternative, I tried using VirtGraph as follows:

VirtGraph virtGraphTest = new VirtGraph("http://test.org", "jdbc:virtuoso://localhost:1111/charset=UTF-8", <usr>, <pass>);
virtGraphTest.read("file://test/test.ttl", "TTL");
virtGraphTest.close();
VirtGraph virtGraphTestA = new VirtGraph("http://testA.org", "jdbc:virtuoso://localhost:1111/charset=UTF-8", <usr>, <pass>);
virtGraphTestA.read("file://test/testA.ttl", "TTL");
virtGraphTestA.close();
VirtGraph virtGraph = new VirtGraph("jdbc:virtuoso://localhost:1111/charset=UTF-8", <usr>, <pass>);

String queryStringTest = " prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
        prefix cc: <http://example.org/cc/>
        SELECT ?c1 ?sx ?c2 ?m
        FROM <http://test.org>
        WHERE { ?c1 rdf:type cc:Test1; cc:p11 ?sx.
         ?c2 rdf:type cc:Test2; cc:p21 ?sx; cc:p22 ?m.
         FILTER EXISTS { GRAPH ?g {?m cc:p cc:M.} FILTER(?g=<http://testA.org>) }
        }";
Query queryTest = QueryFactory.create(queryStringTest);
VirtuosoQueryExecution qet = VirtuosoQueryExecutionFactory.create(queryTest, virtGraph);
ResultSet rst = qet.execSelect();
while (rst.hasNext()) {
    System.out.println(rst.next());
}
qet.close();
virtGraph.close();

This seems to work fine.

Note that in the GRAPH declaration of the SPARQL query, I use GRAPH ?g and then FILTER (?g=<http://testA.org>) in order to specify the named graph.

If I use GRAPH <http://testA.org> instead, the query is parsed but the GRAPH declaration seems to be ignored, based on the query result.

Which is the correct way of invoking a GRAPH within the SPARQL query for Virtuoso?

In general I was wondering which is the best practice for handling RDF datasets and SPARQL queries invoking default and named RDF graphs in Virtuoso?

I have made a Google search for these issues but I have not seen an enlightening example.

Sorry for the long post and thank you in advance!

1

There are 1 answers

0
Sergey Malinin On BEST ANSWER

The procedure DB.DBA.rdf_insert_triple_c is built into the Virtuoso server, and it didn't exist in old versions of Virtuoso 6.x (your version dates from 2013 or earlier).

You can install a current version of Virtuoso server 7.x (strongly recommended), or use an old version of the Virtuoso Jena provider for Virtuoso 6.x.