The following code will always return true
regardless of the existence of statements with that subject:
BNode subject = SimpleValueFactory.getInstance().createBNode( "some-id" );
connection.hasStatement( subject, null, null, false );
In the past this code used to work since the implementation of hasStatement
was the one that AbstractRepositoryConnection
has, but recently this was changed to use a SPARQL query instead. Since SPARQL queries can't reference BNodes directly, the subject gets replaced by a SPARQL variable and returns true always.
Workaround
To make it work, we changed the implementation of the method to:
public boolean hasStatement( Resource subj, IRI pred, Value obj, boolean includeInferred, Resource... contexts ) throws RepositoryException {
StringBuilder triplePattern = new StringBuilder( "{ " );
StringBuilder auxiliaryPatterns = new StringBuilder();
// Subject
if ( subj == null ) {
triplePattern.append( " ?s" );
} else if ( subj instanceof BNode ) {
triplePattern.append( " ?s" );
auxiliaryPatterns.append( " FILTER( STR( ?s ) = \"" ).append( ( (BNode) subj ).getID() ).append( "\" ) ." );
} else {
triplePattern.append( " " ).append( SesameQueryUtils.getSPARQLQueryString( APIMapping.toSesameValue( subj ) ) );
}
// Predicate
if ( pred == null ) {
triplePattern.append( " ?p" );
} else {
triplePattern.append( " " ).append( SesameQueryUtils.getSPARQLQueryString( APIMapping.toSesameValue( pred ) ) );
}
// Object
if ( obj == null ) {
triplePattern.append( " ?o" );
} else if ( obj instanceof BNode ) {
triplePattern.append( " ?o" );
auxiliaryPatterns.append( " FILTER( STR( ?o ) = \"" ).append( ( (BNode) obj ).getID() ).append( "\" ) ." );
} else {
triplePattern.append( " " ).append( SesameQueryUtils.getSPARQLQueryString( APIMapping.toSesameValue( obj ) ) );
}
triplePattern.append( " ." )
.append( auxiliaryPatterns )
.append( " }" );
if ( contexts.length > 0 ) {
for ( Resource context : contexts ) {
String query = String.format( "ASK { GRAPH <%s> %s }", context.stringValue(), triplePattern );
if ( this.mConnection.ask( query ).reasoning( includeInferred ).execute() ) return true;
}
return false;
} else {
String query = String.format( "ASK %s", triplePattern );
return this.mConnection.ask( query ).reasoning( includeInferred ).execute();
}
}
Environment
- Stardog: 5.3.4
- rdf4j-stardog: 5.3.4