diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8cafaa3d4..6ad2b4db7 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -12,9 +12,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 17 diff --git a/CHANGELOG.md b/CHANGELOG.md index b6a9944f3..a5b0f03a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # JOPA - Change Log +### 2.9.4 - 2026-04-17 + +- Change return type of `CriteriaBuilder.langMatches` to `Predicate` to allow including it in predicate lists. +- Fix an issue with instances of subclasses of parents containing inferred attributes not being evicted from cache after + transaction commit. +- Dependency updates: RDF4J 5.3.0. + ### 2.9.3 - 2026-03-16 - Fix driver-level transaction not being started when JOPA transaction starts with a query (Bug #426). @@ -53,8 +60,10 @@ - Support entity classes with subclasses by the entity loading optimizer (Enhancement #357). - Support entity loading optimization in query result stream (Enhancement #357). -- Always resolve the most specific entity classes for instantiation (instead of preferring class exactly matching the requested type). -- Eagerly generate lazy loading entity proxy classes for entity classes that are actually referenced by attributes with fetchType=LAZY in the model (Enhancement #380). +- Always resolve the most specific entity classes for instantiation (instead of preferring class exactly matching the + requested type). +- Eagerly generate lazy loading entity proxy classes for entity classes that are actually referenced by attributes with + fetchType=LAZY in the model (Enhancement #380). - Dependency updates: Jena 5.6.0. ### 2.6.3 - 2025-10-07 diff --git a/datatype/pom.xml b/datatype/pom.xml index a3503f297..a38f766a4 100644 --- a/datatype/pom.xml +++ b/datatype/pom.xml @@ -6,7 +6,7 @@ jopa-all cz.cvut.kbss.jopa - 2.9.3 + 2.9.4 ../pom.xml diff --git a/jopa-api/pom.xml b/jopa-api/pom.xml index 5453dfe19..295e01174 100644 --- a/jopa-api/pom.xml +++ b/jopa-api/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml diff --git a/jopa-api/src/main/java/cz/cvut/kbss/jopa/model/query/criteria/CriteriaBuilder.java b/jopa-api/src/main/java/cz/cvut/kbss/jopa/model/query/criteria/CriteriaBuilder.java index b4a85f255..55e6cf8ef 100644 --- a/jopa-api/src/main/java/cz/cvut/kbss/jopa/model/query/criteria/CriteriaBuilder.java +++ b/jopa-api/src/main/java/cz/cvut/kbss/jopa/model/query/criteria/CriteriaBuilder.java @@ -138,7 +138,7 @@ public interface CriteriaBuilder extends PredicateFactory { * @param range Language range expression * @return Function call expression */ - Expression langMatches(Expression value, Expression range); + Predicate langMatches(Expression value, Expression range); /** * Creates an expression for checking if the specified value matches the specified language range. @@ -147,7 +147,7 @@ public interface CriteriaBuilder extends PredicateFactory { * @param range Language range literal * @return Function call expression */ - Expression langMatches(Expression value, String range); + Predicate langMatches(Expression value, String range); /** * Create an ordering by the ascending value of the expression. diff --git a/jopa-distribution/pom.xml b/jopa-distribution/pom.xml index 1ac81b722..2009c9c66 100644 --- a/jopa-distribution/pom.xml +++ b/jopa-distribution/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml diff --git a/jopa-impl/pom.xml b/jopa-impl/pom.xml index d4231b6af..f74296bf7 100644 --- a/jopa-impl/pom.xml +++ b/jopa-impl/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/metamodel/MetamodelBuilder.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/metamodel/MetamodelBuilder.java index c576f1fc2..0ed5b0da9 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/metamodel/MetamodelBuilder.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/metamodel/MetamodelBuilder.java @@ -155,17 +155,13 @@ private void processManagedType(TypeBuilderContext context) { fieldProcessor.processField(f); } - if (!type.isAbstract()) { - try { - type.getIdentifier(); - } catch (IllegalArgumentException e) { - throw new MetamodelInitializationException("Missing identifier field in entity " + cls); - } - } - + verifyIdentifierPresence(type); if (type.getPersistenceType() == Type.PersistenceType.ENTITY) { resolveInheritanceType((IdentifiableEntityType) type); } + if (supertypes.stream().anyMatch(st -> inferredClasses.contains(st.getJavaType()))) { + addInferredClass(cls); + } queryProcessor.processClass(cls); } @@ -195,6 +191,16 @@ private Set> processSupertypes(Class return superTypes; } + private static void verifyIdentifierPresence(AbstractIdentifiableType type) { + if (!type.isAbstract()) { + try { + type.getIdentifier(); + } catch (IllegalArgumentException e) { + throw new MetamodelInitializationException("Missing identifier field in entity " + type.getJavaType()); + } + } + } + private static boolean canDeclareInheritanceStrategy(IdentifiableType et) { return et.getSupertypes() == null || et.getSupertypes() .stream() diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderImpl.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderImpl.java index d0ebdb485..34cc8b744 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderImpl.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderImpl.java @@ -153,12 +153,12 @@ public Expression lang(Path x) { } @Override - public Expression langMatches(Expression value, Expression range) { - return new LangMatchesFunction(this, (AbstractExpression) value, (AbstractExpression) range); + public Predicate langMatches(Expression value, Expression range) { + return new SimplePredicateImpl(new LangMatchesFunction(this, (AbstractExpression) value, (AbstractExpression) range), this); } @Override - public Expression langMatches(Expression value, String range) { + public Predicate langMatches(Expression value, String range) { return langMatches(value, new ExpressionLiteralImpl<>(range, this)); } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/model/metamodel/MetamodelBuilderTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/model/metamodel/MetamodelBuilderTest.java index 5b4e2ea5f..ed7679eed 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/model/metamodel/MetamodelBuilderTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/model/metamodel/MetamodelBuilderTest.java @@ -80,6 +80,7 @@ import static org.hamcrest.CoreMatchers.containsStringIgnoringCase; import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; @@ -757,4 +758,27 @@ public static class ClassWithLazySingularAttribute { @OWLObjectProperty(iri = Vocabulary.ATTRIBUTE_BASE + "lazyAttribute", fetch = FetchType.LAZY) private OWLClassA lazyAttribute; } + + @Test + void buildMetamodelIncludesSubtypesOfMappedSuperclassWithInferredAttributeInInferredClasses() { + when(finderMock.getEntities()).thenReturn(Set.of(MappedSuperclassWithInferredAttribute.class, SubClassWithInferredParent.class)); + builder.buildMetamodel(finderMock); + assertThat(builder.getInferredClasses(), hasItems(MappedSuperclassWithInferredAttribute.class, SubClassWithInferredParent.class)); + } + + @TestLocal + @MappedSuperclass + public static class MappedSuperclassWithInferredAttribute { + @Id + private URI id; + + @Inferred + @OWLObjectProperty(iri = Vocabulary.ATTRIBUTE_BASE + "parentInferredAttribute") + private URI parentInferredAttribute; + } + + @TestLocal + @OWLClass(iri = Vocabulary.CLASS_BASE + "SubClassWithInferredParent") + public static class SubClassWithInferredParent extends MappedSuperclassWithInferredAttribute { + } } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaQueryTranslateQueryTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaQueryTranslateQueryTest.java index 542fe2cc3..30c5c2be6 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaQueryTranslateQueryTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaQueryTranslateQueryTest.java @@ -147,6 +147,18 @@ void translateQuerySupportsLangMatches() { assertEquals(expectedSoqlQuery, generatedSoqlQuery); } + @Test + void translateQuerySupportsLangMatchesInListOfRestrictions() { + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); + Root root = query.from(OWLClassA.class); + final List restrictions = List.of(cb.langMatches(root.getAttr("stringAttribute"), "en")); + query.select(root).where(restrictions); + + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); + final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE LANGMATCHES(owlclassa.stringAttribute, :generatedName0)"; + assertEquals(expectedSoqlQuery, generatedSoqlQuery); + } + @Test void translateQuerySupportsSelectionByIdentifierInParameter() { CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); diff --git a/jopa-integration-tests-jena/pom.xml b/jopa-integration-tests-jena/pom.xml index eb74cac73..bbb68a512 100644 --- a/jopa-integration-tests-jena/pom.xml +++ b/jopa-integration-tests-jena/pom.xml @@ -5,7 +5,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml 4.0.0 diff --git a/jopa-integration-tests-owlapi/pom.xml b/jopa-integration-tests-owlapi/pom.xml index 3289515a5..a091e97bb 100644 --- a/jopa-integration-tests-owlapi/pom.xml +++ b/jopa-integration-tests-owlapi/pom.xml @@ -5,7 +5,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml 4.0.0 diff --git a/jopa-integration-tests-rdf4j/pom.xml b/jopa-integration-tests-rdf4j/pom.xml index 464eecac0..0bf6b1496 100644 --- a/jopa-integration-tests-rdf4j/pom.xml +++ b/jopa-integration-tests-rdf4j/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml jopa-integration-tests-rdf4j diff --git a/jopa-integration-tests-virtuoso/pom.xml b/jopa-integration-tests-virtuoso/pom.xml index 4943be421..0b858e2c1 100644 --- a/jopa-integration-tests-virtuoso/pom.xml +++ b/jopa-integration-tests-virtuoso/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 jopa-integration-tests-virtuoso diff --git a/jopa-integration-tests/pom.xml b/jopa-integration-tests/pom.xml index df88fbfd5..92cfb0d90 100644 --- a/jopa-integration-tests/pom.xml +++ b/jopa-integration-tests/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml 4.0.0 diff --git a/jopa-maven-plugin/pom.xml b/jopa-maven-plugin/pom.xml index 828e06a7b..156c57b66 100644 --- a/jopa-maven-plugin/pom.xml +++ b/jopa-maven-plugin/pom.xml @@ -5,7 +5,7 @@ jopa-all cz.cvut.kbss.jopa - 2.9.3 + 2.9.4 ../pom.xml 4.0.0 diff --git a/jopa-owl2java/pom.xml b/jopa-owl2java/pom.xml index ad420bd33..809e41555 100644 --- a/jopa-owl2java/pom.xml +++ b/jopa-owl2java/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml diff --git a/jopa-owlapi-utils/pom.xml b/jopa-owlapi-utils/pom.xml index 294ff5153..d6e97a42d 100644 --- a/jopa-owlapi-utils/pom.xml +++ b/jopa-owlapi-utils/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml diff --git a/modelgen/pom.xml b/modelgen/pom.xml index c93cf6c7d..53ed75dda 100644 --- a/modelgen/pom.xml +++ b/modelgen/pom.xml @@ -6,7 +6,7 @@ jopa-all cz.cvut.kbss.jopa - 2.9.3 + 2.9.4 ../pom.xml diff --git a/ontodriver-api/pom.xml b/ontodriver-api/pom.xml index 18f46529a..0c54de62c 100644 --- a/ontodriver-api/pom.xml +++ b/ontodriver-api/pom.xml @@ -6,7 +6,7 @@ jopa-all cz.cvut.kbss.jopa - 2.9.3 + 2.9.4 ../pom.xml diff --git a/ontodriver-jena/pom.xml b/ontodriver-jena/pom.xml index f8ae1a67f..f13e29357 100644 --- a/ontodriver-jena/pom.xml +++ b/ontodriver-jena/pom.xml @@ -8,7 +8,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml diff --git a/ontodriver-owlapi/pom.xml b/ontodriver-owlapi/pom.xml index 1e74011fd..7ff0213e5 100644 --- a/ontodriver-owlapi/pom.xml +++ b/ontodriver-owlapi/pom.xml @@ -11,7 +11,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ../pom.xml diff --git a/ontodriver-rdf4j/pom.xml b/ontodriver-rdf4j/pom.xml index b159ae42d..fc04f00e3 100644 --- a/ontodriver-rdf4j/pom.xml +++ b/ontodriver-rdf4j/pom.xml @@ -10,11 +10,11 @@ jopa-all cz.cvut.kbss.jopa - 2.9.3 + 2.9.4 - 5.2.2 + 5.3.0 diff --git a/ontodriver-virtuoso/pom.xml b/ontodriver-virtuoso/pom.xml index 1b615f3cb..077d34210 100644 --- a/ontodriver-virtuoso/pom.xml +++ b/ontodriver-virtuoso/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 2.9.3 + 2.9.4 ontodriver-virtuoso diff --git a/pom.xml b/pom.xml index b230db2b7..1ef892312 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 cz.cvut.kbss.jopa - 2.9.3 + 2.9.4 jopa-all pom JOPA @@ -44,7 +44,7 @@ 2.0.17 6.0.2 5.21.0 - 1.5.26 + 1.5.32 5.5.1