Steps to reproduce
Having the following statement stored in the DB:
_:some-id rdf:label "Some BNode" .
The following code:
BNode subject = SimpleValueFactory.getInstance().createBNode( "some-id" );
connection.getStatements( subject, RDF.label, null, false );
Won't return results (but in previous versions it did). The cause is that the implementation is comparing the subject on a CONSTRUCT
query directly (FILTER ( ?subject = _:some-id )
) (which will always return false
).
Workaround
To make it work, we changed the implementation of the method so it compares the string representation of BNodes instead:
public RepositoryResult<Statement> getStatements( Resource subj, IRI pred, Value obj, boolean theIncludeInferred, Resource... contexts ) throws RepositoryException {
try {
List<org.openrdf.model.IRI> namedGraphs = contexts.length > 0
? Arrays.stream( contexts )
.filter( ( context ) -> context instanceof IRI )
.map( ( context ) -> APIMapping.toSesameIRI( (IRI) context ) )
.collect( Collectors.toList() )
: Collections.singletonList( Contexts.ALL );
org.openrdf.query.Dataset dataset = ImmutableDataset.builder().namedGraphs( namedGraphs ).build();
StringBuilder query = new StringBuilder( "construct { graph ?g {?s ?p ?o} } where { graph ?g {?s ?p ?o} " );
if ( subj != null ) {
if ( subj instanceof BNode ) {
query.append( "\nfilter (STR(?s) = \"" ).append( ( (BNode) subj ).getID() ).append( "\")" );
} else {
query.append( String.format( "%nfilter (?s = %s)", SesameQueryUtils.getARQSPARQLQueryString( APIMapping.toSesameResource( subj ) ) ) );
}
}
if ( pred != null ) {
query.append( String.format( "%nfilter (?p = %s)", SesameQueryUtils.getSPARQLQueryString( APIMapping.toSesameIRI( pred ) ) ) );
}
if ( obj != null ) {
if ( subj instanceof BNode ) {
query.append( "\nfilter (STR(?o) = \"" ).append( ( (BNode) subj ).getID() ).append( "\")" );
} else {
query.append( String.format( "%nfilter (?o = %s)", SesameQueryUtils.getARQSPARQLQueryString( APIMapping.toSesameValue( obj ) ) ) );
}
}
query.append( "}" );
org.openrdf.query.GraphQueryResult result = this.mConnection.graph( query.toString() ).dataset( dataset ).reasoning( theIncludeInferred ).execute();
Stream<Statement> resultStream = Iterations.stream( APIMapping.toRDF4jGraphQueryResult( result ) );
return new RepositoryResult<>( new StardogRepositoryConnection.SesameIterationAdapter<>( resultStream.onClose( result::close ) ) );
} catch ( StardogException e ) {
LOGGER.error( "Get statements failure", e );
throw new RepositoryException( "There was an error while getting statements" );
}
}
Environment
- Stardog: 5.3.4
- rdf4j-stardog: 5.3.4