Skip to content

Commit

Permalink
[Enhancement #245] Flush reasoner before executing query to purge pos…
Browse files Browse the repository at this point in the history
…sibly stale reasoner cache.
  • Loading branch information
ledsoft committed Jul 22, 2024
1 parent bb84e2c commit e6ceb1e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ void testSelectByTypeAndDataPropertyValue() {
"?stringAtt ?bString . }";
final TypedQuery<OWLClassB> q = getEntityManager().createNativeQuery(query, OWLClassB.class);
q.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_B))
.setParameter("stringAtt", URI.create(Vocabulary.P_B_STRING_ATTRIBUTE))
.setParameter("bString", b.getStringAttribute(), "en");
.setParameter("stringAtt", URI.create(Vocabulary.P_B_STRING_ATTRIBUTE))
.setParameter("bString", b.getStringAttribute(), "en");
final OWLClassB res = q.getSingleResult();
assertNotNull(res);
assertEquals(b.getUri(), res.getUri());
Expand All @@ -113,10 +113,9 @@ void testSelectByObjectProperty() {
final List<OWLClassD> ds = new ArrayList<>(QueryTestEnvironment.getData(OWLClassD.class));
final OWLClassA a = ds.get(Generators.randomPositiveInt(2, ds.size())).getOwlClassA();
final TypedQuery<OWLClassD> q = getEntityManager().createNativeQuery(query, OWLClassD.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_D))
.setParameter("hasA",
URI.create(Vocabulary.P_HAS_OWL_CLASS_A))
.setParameter("y", a.getUri());
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_D))
.setParameter("hasA", URI.create(Vocabulary.P_HAS_OWL_CLASS_A))
.setParameter("y", a.getUri());

final List<OWLClassD> expected = ds.stream().filter(d -> d.getOwlClassA().getUri().equals(a.getUri())).toList();
final List<OWLClassD> res = q.getResultList();
Expand All @@ -126,7 +125,7 @@ void testSelectByObjectProperty() {
@Test
void testSetMaxResults() {
final TypedQuery<OWLClassE> q = getEntityManager().createNativeQuery(SELECT_BY_TYPE, OWLClassE.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_E));
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_E));
final int max = 5;
assertTrue(max < QueryTestEnvironment.getData(OWLClassE.class).size());
assertEquals(Integer.MAX_VALUE, q.getMaxResults());
Expand All @@ -141,14 +140,14 @@ void testSetMaxResults() {
@Test
void testSetMaxResultsNegative() {
final TypedQuery<OWLClassE> q = getEntityManager().createNativeQuery(SELECT_BY_TYPE, OWLClassE.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_E));
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_E));
assertThrows(IllegalArgumentException.class, () -> q.setMaxResults(-1));
}

@Test
void testSetMaxResultsZero() {
final TypedQuery<OWLClassE> q = getEntityManager().createNativeQuery(SELECT_BY_TYPE, OWLClassE.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_E));
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_E));
q.setMaxResults(0);
final List<OWLClassE> res = q.getResultList();
assertNotNull(res);
Expand All @@ -162,7 +161,7 @@ void testGetSingleResult() {
"SELECT ?x WHERE { ?x ?stringAtt ?aString .}";
final TypedQuery<OWLClassA> q = getEntityManager().createNativeQuery(query, OWLClassA.class);
q.setParameter("stringAtt", URI.create(Vocabulary.P_A_STRING_ATTRIBUTE))
.setParameter("aString", a.getStringAttribute(), "en");
.setParameter("aString", a.getStringAttribute(), "en");
final OWLClassA res = q.getSingleResult();
assertNotNull(res);
assertEquals(a.getUri(), res.getUri());
Expand All @@ -171,7 +170,7 @@ void testGetSingleResult() {
@Test
void testGetSingleResultMultiples() {
final TypedQuery<OWLClassE> q = getEntityManager().createNativeQuery(SELECT_BY_TYPE, OWLClassE.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_E));
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_E));
assertThrows(NoUniqueResultException.class, q::getSingleResult);
}

Expand Down Expand Up @@ -199,7 +198,7 @@ void testCreateQueryNullClass() {
void askQueryReturnsTrue() {
final String query = "ASK { ?x a ?type . }";
final TypedQuery<Boolean> q = getEntityManager().createNativeQuery(query, Boolean.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_A));
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_A));
final Boolean res = q.getSingleResult();
assertNotNull(res);
assertTrue(res);
Expand All @@ -217,17 +216,19 @@ void askQueryReturnsFalse() {

@Test
public void askQueryAgainstTransactionalOntologyContainsUncommittedChangesAsWell() {
final OWLClassE e = new OWLClassE();
final OWLClassD d = QueryTestEnvironment.getData(OWLClassD.class).get(0);
final OWLClassA a = QueryTestEnvironment.getData(OWLClassA.class).get(1);
getEntityManager().getTransaction().begin();
try {
getEntityManager().persist(e);
final TypedQuery<Boolean> query = getEntityManager().createNativeQuery(
"ASK { ?individual a ?type . }",
Boolean.class).setParameter("individual", e.getUri()).setParameter("type",
URI.create(Vocabulary.C_OWL_CLASS_E));
final OWLClassD update = getEntityManager().find(OWLClassD.class, d.getUri());
final OWLClassA toAssign = getEntityManager().find(OWLClassA.class, a.getUri());
update.setOwlClassA(toAssign);
final TypedQuery<URI> query = getEntityManager().createNativeQuery("SELECT ?a WHERE { ?d ?hasA ?a . }", URI.class)
.setParameter("d", update.getUri())
.setParameter("hasA", URI.create(Vocabulary.P_HAS_OWL_CLASS_A));
query.setHint(QueryHints.TARGET_ONTOLOGY, Statement.StatementOntology.TRANSACTIONAL.toString());
final Boolean res = query.getSingleResult();
assertTrue(res);
final URI res = query.getSingleResult();
assertEquals(a.getUri(), res);
} finally {
getEntityManager().getTransaction().rollback();
}
Expand All @@ -238,7 +239,7 @@ void askQueryWithPositionParameter() {
final String query = "ASK { ?x a $1 . }";
final URI paramValue = URI.create(OWLClassA.class.getAnnotation(OWLClass.class).iri());
final TypedQuery<Boolean> q = getEntityManager().createNativeQuery(query, Boolean.class)
.setParameter(1, paramValue);
.setParameter(1, paramValue);
final Boolean res = q.getSingleResult();
assertNotNull(res);
assertTrue(res);
Expand All @@ -249,7 +250,7 @@ void testCreateTypedNamedNativeQuery() {
final List<OWLClassA> expected = QueryTestEnvironment.getData(OWLClassA.class);
final List<URI> uris = expected.stream().map(OWLClassA::getUri).toList();
final List<OWLClassA> res = getEntityManager().createNamedQuery("OWLClassA.findAll", OWLClassA.class)
.getResultList();
.getResultList();
assertEquals(expected.size(), res.size());
res.forEach(a -> assertTrue(uris.contains(a.getUri())));
}
Expand All @@ -261,7 +262,7 @@ void usingDescriptorAllowsToCustomizeQueryResults() {
final Descriptor descriptor = new EntityDescriptor();
descriptor.setLanguage("cs");
final List<OWLClassA> result = getEntityManager().createNamedQuery("OWLClassA.findAll", OWLClassA.class)
.setDescriptor(descriptor).getResultList();
.setDescriptor(descriptor).getResultList();
assertEquals(expected.size(), result.size());
result.forEach(a -> assertNull(a.getStringAttribute())); // Because the data has @en language tag
}
Expand All @@ -271,9 +272,9 @@ public void usingUntypedQueryAllowsToSpecifyLimitInQuery() {
final List<OWLClassA> expected = QueryTestEnvironment.getData(OWLClassA.class);
final int size = expected.size() / 2;
final List<OWLClassA> result = getEntityManager().createNativeQuery("SELECT ?x WHERE {" +
"?x a ?classA . } LIMIT ?limit", OWLClassA.class)
.setParameter("classA", URI.create(Vocabulary.C_OWL_CLASS_A))
.setUntypedParameter("limit", size).getResultList();
"?x a ?classA . } LIMIT ?limit", OWLClassA.class)
.setParameter("classA", URI.create(Vocabulary.C_OWL_CLASS_A))
.setUntypedParameter("limit", size).getResultList();
assertEquals(size, result.size());
}

Expand All @@ -283,7 +284,7 @@ public void setFirstResultCanBeUsedToOffsetFirstQueryResult() {
expected.sort(Comparator.comparing(OWLClassA::getUri));
final int offset = expected.size() / 2;
final List<OWLClassA> result = getEntityManager().createNamedQuery("OWLClassA.findAll", OWLClassA.class)
.setFirstResult(offset).getResultList();
.setFirstResult(offset).getResultList();
assertEquals(expected.size() - offset, result.size());
for (int i = 0; i < result.size(); i++) {
assertEquals(expected.get(i + offset).getUri(), result.get(i).getUri());
Expand All @@ -308,14 +309,14 @@ void selectionByObjectPropertySupportsEntityAsQueryParameter() {
final List<OWLClassD> ds = new ArrayList<>(QueryTestEnvironment.getData(OWLClassD.class));
final OWLClassA a = ds.get(Generators.randomPositiveInt(2, ds.size())).getOwlClassA();
final TypedQuery<OWLClassD> q = getEntityManager().createNativeQuery(query, OWLClassD.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_D))
.setParameter("hasA",
URI.create(Vocabulary.P_HAS_OWL_CLASS_A))
.setParameter("y", a);
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_D))
.setParameter("hasA",
URI.create(Vocabulary.P_HAS_OWL_CLASS_A))
.setParameter("y", a);

final List<OWLClassD> expected = ds.stream().filter(d -> d.getOwlClassA().getUri().equals(a.getUri()))
.sorted(Comparator.comparing(OWLClassD::getUri))
.toList();
.sorted(Comparator.comparing(OWLClassD::getUri))
.toList();
final List<OWLClassD> res = q.getResultList();
res.sort(Comparator.comparing(OWLClassD::getUri));
assertEquals(expected.size(), res.size());
Expand All @@ -329,12 +330,12 @@ void selectionByObjectPropertySupportsEntityAsQueryParameter() {
protected void querySupportsCollectionParameters() {
final String query = "SELECT ?x WHERE { ?x a ?type . FILTER (?x IN (?values)) }";
final List<OWLClassA> as = QueryTestEnvironment.getData(OWLClassA.class).stream()
.filter(a -> Generators.randomBoolean())
.toList();
.filter(a -> Generators.randomBoolean())
.toList();
final TypedQuery<OWLClassA> q = getEntityManager().createNativeQuery(query, OWLClassA.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_A))
.setParameter("values", as.stream().map(OWLClassA::getUri)
.toList());
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_A))
.setParameter("values", as.stream().map(OWLClassA::getUri)
.toList());
final List<OWLClassA> result = q.getResultList();
assertEquals(as.size(), result.size());
for (OWLClassA exp : as) {
Expand All @@ -357,11 +358,13 @@ protected void querySupportsSelectionByDate() {
getEntityManager().getTransaction().commit();
final LocalDateTime param = LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS).minusHours(3);
final List<OWLClassM> matching = mInstances.stream()
.filter(m -> m.getDateAttribute().toInstant().atOffset(ZoneOffset.UTC).isBefore(param.atOffset(ZoneOffset.UTC)))
.toList();
.filter(m -> m.getDateAttribute().toInstant()
.atOffset(ZoneOffset.UTC)
.isBefore(param.atOffset(ZoneOffset.UTC)))
.toList();
try {
final List<OWLClassM> result = getEntityManager().createQuery("SELECT m FROM OWLClassM m WHERE m.dateAttribute < :date", OWLClassM.class)
.setParameter("date", param).getResultList();
.setParameter("date", param).getResultList();
assertEquals(matching.size(), result.size());
matching.forEach(m -> assertTrue(result.stream().anyMatch(rm -> rm.getKey().equals(m.getKey()))));
} finally {
Expand All @@ -372,17 +375,17 @@ protected void querySupportsSelectionByDate() {
private void cleanupTestData(String type) {
getEntityManager().getTransaction().begin();
getEntityManager().createNativeQuery("DELETE WHERE { ?x a ?type . ?x ?y ?z . }")
.setParameter("type", URI.create(type)).executeUpdate();
.setParameter("type", URI.create(type)).executeUpdate();
getEntityManager().getTransaction().commit();
}

@Test
protected void querySupportsSelectionByEntityIdentifier() {
final OWLClassA entity = Generators.getRandomItem(QueryTestEnvironment.getData(OWLClassA.class));
final OWLClassA result = getEntityManager().createNativeQuery("SELECT ?x WHERE { ?x a ?type . }", OWLClassA.class)
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_A))
.setParameter("x", entity.getUri())
.getSingleResult();
.setParameter("type", URI.create(Vocabulary.C_OWL_CLASS_A))
.setParameter("x", entity.getUri())
.getSingleResult();
assertEquals(entity.getUri(), result.getUri());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.reasoner.OWLReasoner;

public class LiveOntologyStatementExecutor implements StatementExecutor {
class LiveOntologyStatementExecutor implements StatementExecutor {

private final Connector connector;

Expand All @@ -55,6 +55,8 @@ private QueryResult<OWLObject> execute(QuerySpecification query, OntologySnapsho
}
final OWLReasoner reasonerToUse =
query.isDisableInference() ? getNoInferenceReasoner(snapshot) : snapshot.getReasoner();
// Flush the reasoner to have the latest ontology state for query execution
reasonerToUse.flush();
final OWLAPIv3OWL2Ontology ont = new OWLAPIv3OWL2Ontology(snapshot.getOntologyManager(),
snapshot.getOntology(), reasonerToUse);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import cz.cvut.kbss.ontodriver.ResultSet;
import cz.cvut.kbss.ontodriver.owlapi.exception.OwlapiDriverException;

public interface StatementExecutor {
interface StatementExecutor {

/**
* Executes the specified read-only query.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.reasoner.OWLReasoner;

public class TransactionalStatementExecutor implements StatementExecutor {
class TransactionalStatementExecutor implements StatementExecutor {

private final OWLOntology ontology;
private final OWLOntologyManager ontologyManager;
Expand All @@ -52,6 +52,8 @@ private QueryResult<OWLObject> execute(QuerySpecification query) throws OwlapiDr
throw new ReasonerNotAvailableException("Cannot execute query without a reasoner.");
}
final OWLReasoner reasonerToUse = query.isDisableInference() ? getNoInferenceReasoner() : reasoner;
// Flush the reasoner to have the latest ontology state for query execution
reasoner.flush();
final OWLAPIv3OWL2Ontology ont = new OWLAPIv3OWL2Ontology(ontologyManager, ontology, reasonerToUse);

final QueryResult<OWLObject> res = OWL2QueryEngine.exec(query.getQuery(), ont);
Expand Down

0 comments on commit e6ceb1e

Please sign in to comment.