From cf1199270adcda3a7794bb6dd7d4f24f28921474 Mon Sep 17 00:00:00 2001 From: Oliver Grande Date: Fri, 24 Nov 2023 17:13:03 +0100 Subject: [PATCH] Defect/issues239 (#303) * First level of COUNT query as IN * Deletion of JPACollectionFilterQuery --- .../core/edm/annotation/EdmEnumeration.java | 2 +- .../core/edm/annotation/EdmTransient.java | 2 +- jpa/odata-jpa-coverage/pom.xml | 207 +++++++++--------- .../core/edm/mapper/api/JPAJoinTable.java | 9 +- .../impl/IntermediateCollectionProperty.java | 32 ++- .../mapper/impl/JPAAssociationPathImpl.java | 9 +- .../processor/cb/impl/CollectionJoinImpl.java | 18 +- .../jpa/processor/cb/impl/CompoundPath.java | 4 +- .../cb/impl/CollectionJoinImplTest.java | 20 +- .../core/filter/JPAFilterComplierAccess.java | 9 + .../core/filter/JPAFilterElementComplier.java | 13 ++ .../core/filter/JPALambdaOperation.java | 39 ++-- .../core/filter/JPANavigationOperation.java | 34 ++- .../jpa/processor/core/filter/JPAVisitor.java | 10 +- .../core/processor/JPAEmptyDebugger.java | 4 +- .../core/query/ExpressionUtility.java | 4 +- .../core/query/JPAAbstractQuery.java | 24 +- .../core/query/JPAAbstractSubQuery.java | 42 ++-- .../core/query/JPACollectionFilterQuery.java | 178 --------------- .../JPANavigationCountForExistsQuery.java | 4 +- .../query/JPANavigationCountForInQuery.java | 4 +- .../core/query/JPANavigationCountQuery.java | 4 +- .../core/query/JPANavigationFilterQuery.java | 19 +- .../JPANavigationFilterQueryBuilder.java | 39 +++- .../core/query/JPANavigationNullQuery.java | 4 +- .../core/query/JPANavigationPropertyInfo.java | 3 +- .../JPANavigationPropertyInfoAccess.java | 5 + .../core/query/JPANavigationSubQuery.java | 8 +- .../core/filter/TestJPAQueryWhereClause.java | 2 +- .../JPANavigationCountForExistsQueryTest.java | 2 +- .../JPANavigationCountForInQueryTest.java | 2 +- .../query/JPANavigationCountQueryTest.java | 30 ++- .../JPANavigationFilterQueryBuilderTest.java | 34 +-- .../query/JPANavigationFilterQueryTest.java | 13 +- .../query/JPANavigationNullQueryTest.java | 16 +- .../testmodel/BusinessPartnerWithGroups.java | 17 +- .../resources/db/migration/V1_0__olingo.sql | 3 +- jpa/pom.xml | 2 +- 38 files changed, 375 insertions(+), 496 deletions(-) delete mode 100644 jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPACollectionFilterQuery.java diff --git a/jpa/odata-jpa-annotation/src/main/java/com/sap/olingo/jpa/metadata/core/edm/annotation/EdmEnumeration.java b/jpa/odata-jpa-annotation/src/main/java/com/sap/olingo/jpa/metadata/core/edm/annotation/EdmEnumeration.java index e4b84f63d..5a3f524f9 100644 --- a/jpa/odata-jpa-annotation/src/main/java/com/sap/olingo/jpa/metadata/core/edm/annotation/EdmEnumeration.java +++ b/jpa/odata-jpa-annotation/src/main/java/com/sap/olingo/jpa/metadata/core/edm/annotation/EdmEnumeration.java @@ -38,7 +38,7 @@ /** * Converter to convert enumeration value into a number. If no converter is provided, the ordinal is taken. */ - Class[], ? extends Number>> converter() default DummyConverter.class; + Class[], ? extends Number>> converter() default DummyConverter.class; // NOSONAR boolean isFlags() default false; diff --git a/jpa/odata-jpa-annotation/src/main/java/com/sap/olingo/jpa/metadata/core/edm/annotation/EdmTransient.java b/jpa/odata-jpa-annotation/src/main/java/com/sap/olingo/jpa/metadata/core/edm/annotation/EdmTransient.java index 31f25c7ec..dc38aa6f7 100644 --- a/jpa/odata-jpa-annotation/src/main/java/com/sap/olingo/jpa/metadata/core/edm/annotation/EdmTransient.java +++ b/jpa/odata-jpa-annotation/src/main/java/com/sap/olingo/jpa/metadata/core/edm/annotation/EdmTransient.java @@ -33,5 +33,5 @@ * property collection. * @return */ - Class> calculator(); + Class> calculator(); // NOSONAR } diff --git a/jpa/odata-jpa-coverage/pom.xml b/jpa/odata-jpa-coverage/pom.xml index 9d79cc052..84182aa07 100644 --- a/jpa/odata-jpa-coverage/pom.xml +++ b/jpa/odata-jpa-coverage/pom.xml @@ -1,105 +1,110 @@ - - 4.0.0 - - com.sap.olingo - odata-jpa - 2.0.1 - + + 4.0.0 + + com.sap.olingo + odata-jpa + 2.0.1 + - odata-jpa-coverage - odata-jpa-coverage - https://github.com/SAP/olingo-jpa-processor-v4 + odata-jpa-coverage + odata-jpa-coverage + https://github.com/SAP/olingo-jpa-processor-v4 - - UTF-8 - - - - - com.sap.olingo - odata-jpa-annotation - ${project.version} - - - com.sap.olingo - odata-jpa-metadata - ${project.version} - - - com.sap.olingo - odata-jpa-processor - ${project.version} - - - com.sap.olingo - odata-jpa-processor-cb - ${project.version} - - - com.sap.olingo - odata-jpa-processor-ext - ${project.version} - - - com.sap.olingo - odata-jpa-test - ${project.version} - - - com.sap.olingo - odata-jpa-odata-vocabularies - ${project.version} - - - com.sap.olingo - odata-jpa-processor-parallel - ${project.version} - - - com.sap.olingo - odata-jpa-vocabularies - ${project.version} - - + + UTF-8 + - - - - org.jacoco - jacoco-maven-plugin - ${jacoco.version} - - - - prepare-agent - - - - report - prepare-package - - report-aggregate - - - - - - - CLASS - - *Test - - - - - - - org.eluder.coveralls - coveralls-maven-plugin - ${coveralls.version} - - - - pom + + + com.sap.olingo + odata-jpa-annotation + ${project.version} + + + com.sap.olingo + odata-jpa-metadata + ${project.version} + + + com.sap.olingo + odata-jpa-processor + ${project.version} + + + com.sap.olingo + odata-jpa-processor-cb + ${project.version} + + + com.sap.olingo + odata-jpa-processor-ext + ${project.version} + + + com.sap.olingo + odata-jpa-test + ${project.version} + + + com.sap.olingo + odata-jpa-odata-vocabularies + ${project.version} + + + com.sap.olingo + odata-jpa-processor-parallel + ${project.version} + + + com.sap.olingo + odata-jpa-vocabularies + ${project.version} + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + + prepare-agent + + + + report + prepare-package + + report-aggregate + + + + + + com/sap/olingo/jpa/processor/core/testmodel/* + com/sap/olingo/jpa/processor/core/errormodel/* + + + + CLASS + + *Test + + + + + + + org.eluder.coveralls + coveralls-maven-plugin + ${coveralls.version} + + + + pom \ No newline at end of file diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/api/JPAJoinTable.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/api/JPAJoinTable.java index e10d6caad..ef5349cd4 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/api/JPAJoinTable.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/api/JPAJoinTable.java @@ -7,18 +7,19 @@ public interface JPAJoinTable { /** - * Returns the name of the join table including the schema name, using the following pattern: {schema}.{table} - * @return + * @return Name of the join table including the schema name, using the following pattern: {schema}.{table} */ public String getTableName(); + /** + * @return Entity type of the join table + */ public JPAEntityType getEntityType(); public List getJoinColumns() throws ODataJPAModelException; /** - * Returns the list of inverse join columns with exchanged left/right order. - * @return + * @return List of inverse join columns with exchanged left/right order. * @throws ODataJPAModelException */ public List getInverseJoinColumns() throws ODataJPAModelException; diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/IntermediateCollectionProperty.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/IntermediateCollectionProperty.java index 801d652eb..c2f481d12 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/IntermediateCollectionProperty.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/IntermediateCollectionProperty.java @@ -9,6 +9,8 @@ import java.util.ArrayList; import java.util.List; +import javax.annotation.CheckForNull; + import jakarta.persistence.CollectionTable; import jakarta.persistence.JoinColumn; import jakarta.persistence.metamodel.PluralAttribute; @@ -88,7 +90,7 @@ public IntermediateCollectionProperty(final IntermediateCollectionProperty or public JPAAssociationPath asAssociation() throws ODataJPAModelException { if (this.associationPath == null) { getJoinTable(); - this.associationPath = new JPAAssociationPathImpl(this, sourceType, + this.associationPath = new JPAAssociationPathImpl(this, path == null ? sourceType.getPath(getExternalName()) : path, joinTable == null ? null : joinTable.getLeftJoinColumns()); } @@ -111,7 +113,7 @@ public JPAAttribute getTargetAttribute() throws ODataJPAModelException { if (isComplex()) return null; else { - for (final JPAAttribute a : ((IntermediateStructuredType) getJoinTable().getEntityType()).getAttributes()) { + for (final JPAAttribute a : getTargetEntity().getAttributes()) { if (dbFieldName.equals(((IntermediateProperty) a).getDBFieldName())) return a; } @@ -119,9 +121,11 @@ public JPAAttribute getTargetAttribute() throws ODataJPAModelException { } } + @SuppressWarnings("unchecked") @Override public JPAStructuredType getTargetEntity() throws ODataJPAModelException { - return getJoinTable().getEntityType(); + final JPAJoinTable joinInfo = getJoinTable(); + return joinInfo == null ? null : ((IntermediateCollectionTable) joinInfo).getTargetType(); } @Override @@ -209,6 +213,7 @@ String getDefaultValue() throws ODataJPAModelException { return null; } + @CheckForNull JPAJoinTable getJoinTable() throws ODataJPAModelException { if (joinTable == null) { final jakarta.persistence.CollectionTable jpaJoinTable = ((AnnotatedElement) this.jpaAttribute.getJavaMember()) @@ -237,19 +242,23 @@ private Type getRowType() { private class IntermediateCollectionTable implements JPAJoinTable { private final CollectionTable jpaJoinTable; private final List joinColumns; - private final JPAEntityType jpaEntityType; + private final JPAEntityType jpaTargetType; public IntermediateCollectionTable(final CollectionTable jpaJoinTable, final IntermediateSchema schema) throws ODataJPAModelException { super(); this.jpaJoinTable = jpaJoinTable; - this.jpaEntityType = schema.getEntityType(jpaJoinTable.catalog(), jpaJoinTable.schema(), jpaJoinTable.name()); + this.jpaTargetType = schema.getEntityType(jpaJoinTable.catalog(), jpaJoinTable.schema(), jpaJoinTable.name()); this.joinColumns = buildJoinColumns(sourceType); } @Override public JPAEntityType getEntityType() { - return jpaEntityType; + return (JPAEntityType) sourceType; + } + + JPAStructuredType getTargetType() { + return jpaTargetType; } @Override @@ -258,20 +267,21 @@ public List getInverseJoinColumns() throws ODataJPAModelExce for (final IntermediateJoinColumn column : joinColumns) { result.add(new JPAOnConditionItemImpl( - ((IntermediateEntityType) jpaEntityType).getPathByDBField(column.getReferencedColumnName()), - sourceType.getPathByDBField(column.getName()))); + sourceType.getPathByDBField(column.getName()), + ((IntermediateEntityType) jpaTargetType).getPathByDBField(column.getReferencedColumnName()))); } return result; } @Override public List getJoinColumns() throws ODataJPAModelException { - assert jpaEntityType != null; + assert jpaTargetType != null; final List result = new ArrayList<>(); + // Self Join for (final IntermediateJoinColumn column : joinColumns) { result.add(new JPAOnConditionItemImpl( sourceType.getPathByDBField(column.getName()), - ((IntermediateEntityType) jpaEntityType).getPathByDBField(column.getReferencedColumnName()))); + sourceType.getPathByDBField(column.getName()))); } return result; } @@ -327,7 +337,7 @@ else if (!(contextType instanceof IntermediateEntityType)) @Override public List getRightColumnsList() throws ODataJPAModelException { - return getJoinColumns().stream() + return getInverseJoinColumns().stream() .map(JPAOnConditionItem::getRightPath) .toList(); } diff --git a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/JPAAssociationPathImpl.java b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/JPAAssociationPathImpl.java index f880a0376..3f8eaf6d8 100644 --- a/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/JPAAssociationPathImpl.java +++ b/jpa/odata-jpa-metadata/src/main/java/com/sap/olingo/jpa/metadata/core/edm/mapper/impl/JPAAssociationPathImpl.java @@ -79,13 +79,12 @@ final class JPAAssociationPathImpl implements JPAAssociationPath { * @param joinColumns * @throws ODataJPAModelException */ - public JPAAssociationPathImpl(final IntermediateCollectionProperty collectionProperty, - final IntermediateStructuredType source, final JPAPath path, final List joinColumns) - throws ODataJPAModelException { + public JPAAssociationPathImpl(final IntermediateCollectionProperty collectionProperty, final JPAPath path, + final List joinColumns) throws ODataJPAModelException { alias = path.getAlias(); - this.sourceType = source; - this.targetType = null; + this.sourceType = collectionProperty.getSourceType(); + this.targetType = (IntermediateStructuredType) collectionProperty.getTargetEntity(); this.joinColumns = joinColumns; this.pathElements = path.getPath(); this.cardinality = PersistentAttributeType.ONE_TO_MANY; diff --git a/jpa/odata-jpa-processor-cb/src/main/java/com/sap/olingo/jpa/processor/cb/impl/CollectionJoinImpl.java b/jpa/odata-jpa-processor-cb/src/main/java/com/sap/olingo/jpa/processor/cb/impl/CollectionJoinImpl.java index 2d2d3d123..36ede91b1 100644 --- a/jpa/odata-jpa-processor-cb/src/main/java/com/sap/olingo/jpa/processor/cb/impl/CollectionJoinImpl.java +++ b/jpa/odata-jpa-processor-cb/src/main/java/com/sap/olingo/jpa/processor/cb/impl/CollectionJoinImpl.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import javax.annotation.Nonnull; @@ -41,17 +42,15 @@ class CollectionJoinImpl extends AbstractJoinImp { private static JPAPath determinePath(final JPAPath path) throws ODataJPAModelException { return ((JPACollectionAttribute) path.getLeaf()) .asAssociation() - .getJoinTable() - .getEntityType() == null + .getTargetType() == null ? path : null; } private static JPAEntityType determineEt(@Nonnull final JPAPath path, @Nonnull final FromImpl parent) throws ODataJPAModelException { - return Optional.ofNullable(((JPACollectionAttribute) path.getLeaf()) + return (JPAEntityType) Optional.ofNullable(((JPACollectionAttribute) path.getLeaf()) .asAssociation() - .getJoinTable() - .getEntityType()) + .getTargetType()) .orElse(parent.st); } @@ -134,7 +133,7 @@ public JoinType getJoinType() { public int hashCode() { final int prime = 31; int result = super.hashCode(); - result = prime * result + ((attribute == null) ? 0 : attribute.hashCode()); + result = prime * result + Objects.hash(attribute); return result; } @@ -142,11 +141,8 @@ public int hashCode() { public boolean equals(final Object object) { if (this == object) return true; if (!super.equals(object)) return false; - if (getClass() != object.getClass()) return false; + if (!(object instanceof CollectionJoinImpl)) return false; final CollectionJoinImpl other = (CollectionJoinImpl) object; - if (attribute == null) { - if (other.attribute != null) return false; - } else if (!attribute.equals(other.attribute)) return false; - return true; + return Objects.equals(attribute, other.attribute); } } diff --git a/jpa/odata-jpa-processor-cb/src/main/java/com/sap/olingo/jpa/processor/cb/impl/CompoundPath.java b/jpa/odata-jpa-processor-cb/src/main/java/com/sap/olingo/jpa/processor/cb/impl/CompoundPath.java index 326ba9580..764e1690f 100644 --- a/jpa/odata-jpa-processor-cb/src/main/java/com/sap/olingo/jpa/processor/cb/impl/CompoundPath.java +++ b/jpa/odata-jpa-processor-cb/src/main/java/com/sap/olingo/jpa/processor/cb/impl/CompoundPath.java @@ -6,7 +6,7 @@ /** * - * @author D023143 + * @author Oliver Grande * @since 2.0.1 * @created 12.11.2023 */ @@ -14,6 +14,6 @@ interface CompoundPath extends SqlConvertible { boolean isEmpty(); - Path getFirst() throws IllegalStateException; + Path getFirst() throws IllegalStateException; } diff --git a/jpa/odata-jpa-processor-cb/src/test/java/com/sap/olingo/jpa/processor/cb/impl/CollectionJoinImplTest.java b/jpa/odata-jpa-processor-cb/src/test/java/com/sap/olingo/jpa/processor/cb/impl/CollectionJoinImplTest.java index d5430f165..07f6d5a31 100644 --- a/jpa/odata-jpa-processor-cb/src/test/java/com/sap/olingo/jpa/processor/cb/impl/CollectionJoinImplTest.java +++ b/jpa/odata-jpa-processor-cb/src/test/java/com/sap/olingo/jpa/processor/cb/impl/CollectionJoinImplTest.java @@ -1,5 +1,6 @@ package com.sap.olingo.jpa.processor.cb.impl; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -20,6 +21,7 @@ import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; import com.sap.olingo.jpa.processor.cb.ProcessorCriteriaBuilder; import com.sap.olingo.jpa.processor.cb.exceptions.NotImplementedException; +import com.sap.olingo.jpa.processor.core.testmodel.InhouseAddressTable; import com.sap.olingo.jpa.processor.core.testmodel.Person; class CollectionJoinImplTest { @@ -33,6 +35,7 @@ class CollectionJoinImplTest { private JPAJoinTable joinTable; private JPAJoinColumn joinColumn; private JPAEntityType targetType; + private JPAEntityType sourceType; private CollectionJoinImpl cut; @BeforeEach @@ -45,14 +48,20 @@ void setup() throws ODataJPAModelException { joinTable = mock(JPAJoinTable.class); joinColumn = mock(JPAJoinColumn.class); targetType = mock(JPAEntityType.class); + sourceType = mock(JPAEntityType.class); when(path.getLeaf()).thenReturn(attribute); when(attribute.asAssociation()).thenReturn(associationPath); when(attribute.getInternalName()).thenReturn("Test"); when(associationPath.getJoinTable()).thenReturn(joinTable); + when(associationPath.getTargetType()).thenReturn(targetType); + when(associationPath.getSourceType()).thenReturn(sourceType); when(joinTable.getRawInverseJoinInformation()).thenReturn(Arrays.asList(joinColumn)); - when(joinTable.getEntityType()).thenReturn(targetType); - when(targetType.getTypeClass()).thenAnswer(new ClassAnswer(Person.class)); - when(targetType.getInternalName()).thenReturn("Dummy"); + when(joinTable.getEntityType()).thenReturn(sourceType); + when(sourceType.getTypeClass()).thenAnswer(new ClassAnswer(Person.class)); + when(sourceType.getInternalName()).thenReturn("Dummy"); + + when(targetType.getTypeClass()).thenAnswer(new ClassAnswer(InhouseAddressTable.class)); + when(targetType.getInternalName()).thenReturn("InhouseAddressTable"); cut = new CollectionJoinImpl<>(path, parent, ab, cb, null); } @@ -90,4 +99,9 @@ void testEquals() throws ODataJPAModelException { assertFalse(cut.equals(null));// NOSONAR assertFalse(cut.equals("Test"));// NOSONAR } + + @Test + void testDeterminedType() { + assertEquals(targetType, cut.st); + } } diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAFilterComplierAccess.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAFilterComplierAccess.java index 345adc7c8..3d791dbbe 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAFilterComplierAccess.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAFilterComplierAccess.java @@ -18,6 +18,9 @@ interface JPAFilterComplierAccess { + /** + * @return Query a filter belongs to. + */ JPAAbstractQuery getParent(); List getUriResourceParts(); @@ -32,6 +35,12 @@ interface JPAFilterComplierAccess { JPAOperationConverter getConverter(); + /** + * Root of the query the filter belongs to. + * @param + * @param + * @return + */ From getRoot(); JPAServiceDebugger getDebugger(); diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAFilterElementComplier.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAFilterElementComplier.java index 3e9668286..cc876f86b 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAFilterElementComplier.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAFilterElementComplier.java @@ -37,6 +37,19 @@ public final class JPAFilterElementComplier extends JPAAbstractFilter { final JPAAbstractQuery parent; final List groups; + /** + * + * @param odata + * @param sd + * @param em + * @param jpaEntityType + * @param converter + * @param uriResourceParts + * @param parent: Query a filter belongs to. + * @param expression + * @param association + * @param groups + */ public JPAFilterElementComplier(final OData odata, final JPAServiceDocument sd, final EntityManager em, final JPAEntityType jpaEntityType, final JPAOperationConverter converter, final List uriResourceParts, final JPAAbstractQuery parent, final VisitableExpression expression, diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPALambdaOperation.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPALambdaOperation.java index 88f7796c6..6a52a2661 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPALambdaOperation.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPALambdaOperation.java @@ -12,13 +12,11 @@ import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourceLambdaAll; import org.apache.olingo.server.api.uri.UriResourceLambdaAny; -import org.apache.olingo.server.api.uri.UriResourceProperty; import org.apache.olingo.server.api.uri.queryoption.expression.Expression; import org.apache.olingo.server.api.uri.queryoption.expression.Member; import com.sap.olingo.jpa.processor.core.query.JPAAbstractQuery; import com.sap.olingo.jpa.processor.core.query.JPAAbstractSubQuery; -import com.sap.olingo.jpa.processor.core.query.JPACollectionFilterQuery; import com.sap.olingo.jpa.processor.core.query.JPANavigationFilterQueryBuilder; import com.sap.olingo.jpa.processor.core.query.JPANavigationPropertyInfo; import com.sap.olingo.jpa.processor.core.query.JPANavigationPropertyInfoAccess; @@ -27,11 +25,6 @@ abstract class JPALambdaOperation extends JPAExistsOperation { protected final UriInfoResource member; - JPALambdaOperation(final JPAFilterComplierAccess jpaComplier, final UriInfoResource member) { - super(jpaComplier); - this.member = member; - } - JPALambdaOperation(final JPAFilterComplierAccess jpaComplier, final Member member) { super(jpaComplier); this.member = member.getResourcePath(); @@ -57,31 +50,25 @@ protected final Subquery getSubQuery(final Expression expression) for (int i = navigationPathList.size() - 1; i >= 0; i--) { final JPANavigationPropertyInfoAccess navigationInfo = navigationPathList.get(i); if (i == 0) { - if (navigationInfo.getUriResource() instanceof UriResourceProperty) - queryList.add(new JPACollectionFilterQuery(odata, sd, em, parent, member.getUriResourceParts(), expression, - from, groups)); - else - queryList.add(new JPANavigationFilterQueryBuilder(converter.cb) - .setOdata(odata) - .setServiceDocument(sd) - .setUriResourceItem(navigationInfo.getUriResource()) - .setParent(parent) - .setEntityManager(em) - .setAssociation(navigationInfo.getAssociationPath()) - .setExpression(expression) - .setFrom(from) - .setParent(parent) - .setClaimsProvider(claimsProvider) - .setGroups(groups) - .build()); + queryList.add(new JPANavigationFilterQueryBuilder(converter.cb) + .setOdata(odata) + .setServiceDocument(sd) + .setNavigationInfo(navigationInfo) + .setParent(parent) + .setEntityManager(em) + .setExpression(expression) + .setFrom(from) + .setParent(parent) + .setClaimsProvider(claimsProvider) + .setGroups(groups) + .build()); } else { queryList.add(new JPANavigationFilterQueryBuilder(converter.cb) .setOdata(odata) .setServiceDocument(sd) - .setUriResourceItem(navigationInfo.getUriResource()) + .setNavigationInfo(navigationInfo) .setParent(parent) .setEntityManager(em) - .setAssociation(navigationInfo.getAssociationPath()) .setFrom(from) .setParent(parent) .setClaimsProvider(claimsProvider) diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPANavigationOperation.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPANavigationOperation.java index d8c6b703d..7d7d0e32c 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPANavigationOperation.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPANavigationOperation.java @@ -41,7 +41,6 @@ import com.sap.olingo.jpa.processor.core.query.ExpressionUtility; import com.sap.olingo.jpa.processor.core.query.JPAAbstractQuery; import com.sap.olingo.jpa.processor.core.query.JPAAbstractSubQuery; -import com.sap.olingo.jpa.processor.core.query.JPACollectionFilterQuery; import com.sap.olingo.jpa.processor.core.query.JPANavigationFilterQueryBuilder; import com.sap.olingo.jpa.processor.core.query.JPANavigationPropertyInfo; import com.sap.olingo.jpa.processor.core.query.JPANavigationPropertyInfoAccess; @@ -143,32 +142,25 @@ SubQueryItem getExistsQuery() throws ODataApplicationException, ODataJPAIllegalA final JPANavigationPropertyInfoAccess navigationInfo = navigationPathList.get(i); if (i == 0) { expression = createExpression(); - if (navigationInfo.getUriResource() instanceof UriResourceProperty) { - queryList.add(new JPACollectionFilterQuery(odata, sd, em, parent, navigationInfo.getAssociationPath(), - expression, determineFrom(i, navigationPathList.size(), parent), groups)); - } else { - queryList.add(new JPANavigationFilterQueryBuilder(converter.cb) - .setOdata(odata) - .setServiceDocument(sd) - .setUriResourceItem(navigationInfo.getUriResource()) - .setParent(parent) - .setEntityManager(em) - .setAssociation(navigationInfo.getAssociationPath()) - .setExpression(expression) - .setFrom(determineFrom(i, navigationPathList.size(), parent)) - .setParent(parent) - .setClaimsProvider(claimsProvider) - .setGroups(groups) - .build()); - } + queryList.add(new JPANavigationFilterQueryBuilder(converter.cb) + .setOdata(odata) + .setServiceDocument(sd) + .setNavigationInfo(navigationInfo) + .setParent(parent) + .setEntityManager(em) + .setExpression(expression) + .setFrom(determineFrom(i, navigationPathList.size(), parent)) + .setParent(parent) + .setClaimsProvider(claimsProvider) + .setGroups(groups) + .build()); } else { queryList.add(new JPANavigationFilterQueryBuilder(converter.cb) .setOdata(odata) .setServiceDocument(sd) - .setUriResourceItem(navigationInfo.getUriResource()) + .setNavigationInfo(navigationInfo) .setParent(parent) .setEntityManager(em) - .setAssociation(navigationInfo.getAssociationPath()) .setFrom(determineFrom(i, navigationPathList.size(), parent)) .setParent(parent) .setClaimsProvider(claimsProvider) diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAVisitor.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAVisitor.java index 47ba4d361..6ab9a45f7 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAVisitor.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/filter/JPAVisitor.java @@ -173,8 +173,8 @@ public JPAOperator visitLiteral(final Literal literal) throws ExpressionVisitExc public JPAOperator visitMember(final Member member) throws ExpressionVisitException, ODataApplicationException { try (JPARuntimeMeasurement measurement = debugger.newMeasurement(this, "visitMember")) { - final JPAPath attributePath = determineAttributePath(this.jpaComplier.getJpaEntityType(), member, - jpaComplier.getAssociation()); + final JPAPath attributePath = determineAttributePath(this.jpaComplier.getJpaEntityType(), + this.jpaComplier.getParent().getJpaEntity(), member, jpaComplier.getAssociation()); checkTransient(attributePath); if (getLambdaType(member.getResourcePath()) == UriResourceKind.lambdaAny) { return new JPALambdaAnyOperation(this.jpaComplier, member); @@ -294,8 +294,8 @@ private boolean isCustomFunction(final UriInfoResource resourcePath) { } private @Nullable JPAPath determineAttributePath(@Nullable final JPAEntityType jpaEntityType, - @Nonnull final Member member, @Nullable final JPAAssociationPath jpaAssociationPath) - throws ODataApplicationException { + final JPAEntityType parentType, @Nonnull final Member member, + @Nullable final JPAAssociationPath jpaAssociationPath) throws ODataApplicationException { if (jpaEntityType == null) return null; @@ -305,7 +305,7 @@ private boolean isCustomFunction(final UriInfoResource resourcePath) { try { selectItemPath = jpaEntityType.getPath(attributePathName); if (selectItemPath == null && jpaAssociationPath != null) { - selectItemPath = jpaEntityType.getPath(attributePathName.isEmpty() + selectItemPath = jpaAssociationPath.getSourceType().getPath(attributePathName.isEmpty() ? jpaAssociationPath.getAlias() : (jpaAssociationPath.getAlias() + JPAPath.PATH_SEPARATOR + attributePathName)); } diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/processor/JPAEmptyDebugger.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/processor/JPAEmptyDebugger.java index 69c56e4c2..91b1c3c08 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/processor/JPAEmptyDebugger.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/processor/JPAEmptyDebugger.java @@ -16,10 +16,10 @@ public List getRuntimeInformation() { @Override public JPARuntimeMeasurement newMeasurement(final Object instance, final String methodName) { - return new JPAEmptyMeasurment(); + return new JPAEmptyMeasurement(); } - public static class JPAEmptyMeasurment implements JPARuntimeMeasurement { + public static class JPAEmptyMeasurement implements JPARuntimeMeasurement { @Override public void close() { diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/ExpressionUtility.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/ExpressionUtility.java index b6534fdb0..fd6f85e14 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/ExpressionUtility.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/ExpressionUtility.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.stream.Collectors; import jakarta.persistence.AttributeConverter; import jakarta.persistence.criteria.CriteriaBuilder; @@ -114,7 +113,8 @@ public static List> convertToCriteriaPathList(final From root public static List>> convertToCriteriaPaths(final From from, final List jpaPaths) { return jpaPaths.stream() .map(jpaPath -> ExpressionUtility.> convertToCriteriaPath(from, jpaPath.getPath())) - .collect(Collectors.toList()); + .toList(); + // .collect(Collectors.toList()); } public static Object convertValueOnAttribute(final OData odata, final JPAAttribute attribute, final String value) diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPAAbstractQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPAAbstractQuery.java index ce82d564d..a895046fe 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPAAbstractQuery.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPAAbstractQuery.java @@ -94,19 +94,8 @@ public abstract class JPAAbstractQuery { JPAAbstractQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType edmEntityType, final EntityManager em, final Optional claimsProvider) throws ODataApplicationException { - super(); - this.em = em; - this.cb = em.getCriteriaBuilder(); - this.sd = sd; - try { - this.jpaEntity = sd.getEntity(edmEntityType); - } catch (final ODataJPAModelException e) { - throw new ODataJPAQueryException(e, HttpStatusCode.BAD_REQUEST); - } - this.debugger = new JPAEmptyDebugger(); - this.odata = odata; - this.claimsProvider = claimsProvider; - this.groups = Collections.emptyList(); + + this(odata, sd, asJPAEntityType(sd, edmEntityType), em, claimsProvider); } JPAAbstractQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType jpaEntityType, @@ -150,6 +139,15 @@ public JPAServiceDebugger getDebugger() { public abstract From getRoot(); + protected static JPAEntityType asJPAEntityType(final JPAServiceDocument sd, final EdmEntityType edmEntityType) + throws ODataJPAQueryException { + try { + return sd.getEntity(edmEntityType); + } catch (final ODataJPAModelException e) { + throw new ODataJPAQueryException(e, HttpStatusCode.BAD_REQUEST); + } + } + protected jakarta.persistence.criteria.Expression addWhereClause( jakarta.persistence.criteria.Expression whereCondition, final jakarta.persistence.criteria.Expression additionalExpression) { diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPAAbstractSubQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPAAbstractSubQuery.java index bcc9f5f6a..ef00b037d 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPAAbstractSubQuery.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPAAbstractSubQuery.java @@ -55,12 +55,11 @@ public abstract class JPAAbstractSubQuery extends JPAAbstractQuery { protected final JPAAssociationPath association; protected JPAFilterElementComplier filterComplier; - JPAAbstractSubQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType edmEntityType, + JPAAbstractSubQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType jpaEntity, final EntityManager em, final JPAAbstractQuery parent, final From from, - final JPAAssociationPath association, final Optional claimsProvider) - throws ODataApplicationException { + final JPAAssociationPath association, final Optional claimsProvider) { - super(odata, sd, edmEntityType, em, claimsProvider); + super(odata, sd, jpaEntity, em, claimsProvider); this.parentQuery = parent; this.from = from; this.association = association; @@ -70,10 +69,14 @@ public abstract class JPAAbstractSubQuery extends JPAAbstractQuery { final EntityManager em, final JPAAbstractQuery parent, final From from, final JPAAssociationPath association) { - super(odata, sd, jpaEntity, em, Optional.empty()); - this.parentQuery = parent; - this.from = from; - this.association = association; + this(odata, sd, jpaEntity, em, parent, from, association, Optional.empty()); + } + + JPAAbstractSubQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType type, + final EntityManager em, final JPAAbstractQuery parent, final From from, + final JPAAssociationPath association, final Optional claimsProvider) + throws ODataJPAQueryException { + this(odata, sd, asJPAEntityType(type, sd), em, parent, from, association, claimsProvider); } public abstract Subquery getSubQuery(final Subquery childQuery, @@ -126,6 +129,16 @@ protected void createSelectClauseAggregation(final Subquery subQuery, fin setSelection(subQuery, forInExpression, selections); } + protected void createSelectClauseJoin(final Subquery subQuery, final From from, + final List conditionItems, final boolean forInExpression) { + + final List> selections = new ArrayList<>(); + for (final JPAPath item : conditionItems) { + selections.add(ExpressionUtility.convertToCriteriaPath(from, item.getPath())); + } + setSelection(subQuery, forInExpression, selections); + } + @SuppressWarnings("unchecked") private void setSelection(final Subquery subQuery, final boolean forInExpression, final List> selections) { @@ -140,14 +153,13 @@ private void setSelection(final Subquery subQuery, final boolean forInExp subQuery.select((Expression) selections.get(0)); } - protected void createSelectClauseJoin(final Subquery subQuery, final From from, - final List conditionItems, final boolean forInExpression) { - - final List> selections = new ArrayList<>(); - for (final JPAPath item : conditionItems) { - selections.add(ExpressionUtility.convertToCriteriaPath(from, item.getPath())); + private static JPAEntityType asJPAEntityType(final EdmEntityType edmEntityType, final JPAServiceDocument sd) + throws ODataJPAQueryException { + try { + return sd.getEntity(edmEntityType); + } catch (final ODataJPAModelException e) { + throw new ODataJPAQueryException(e, HttpStatusCode.BAD_REQUEST); } - setSelection(subQuery, forInExpression, selections); } protected Expression createWhereByAssociation(final From subRoot, final From parentFrom, diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPACollectionFilterQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPACollectionFilterQuery.java deleted file mode 100644 index ce4d9db6f..000000000 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPACollectionFilterQuery.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.sap.olingo.jpa.processor.core.query; - -import java.util.Collections; -import java.util.List; - -import javax.annotation.Nullable; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.From; -import jakarta.persistence.criteria.JoinType; -import jakarta.persistence.criteria.Path; -import jakarta.persistence.criteria.Subquery; - -import org.apache.olingo.commons.api.http.HttpStatusCode; -import org.apache.olingo.server.api.OData; -import org.apache.olingo.server.api.ODataApplicationException; -import org.apache.olingo.server.api.uri.UriResource; -import org.apache.olingo.server.api.uri.UriResourceCount; -import org.apache.olingo.server.api.uri.UriResourceLambdaAll; -import org.apache.olingo.server.api.uri.UriResourceLambdaAny; -import org.apache.olingo.server.api.uri.queryoption.expression.VisitableExpression; - -import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; -import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; -import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAOnConditionItem; -import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAPath; -import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; -import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; -import com.sap.olingo.jpa.processor.core.exception.ODataJPAIllegalAccessException; -import com.sap.olingo.jpa.processor.core.exception.ODataJPAQueryException; -import com.sap.olingo.jpa.processor.core.filter.JPAFilterElementComplier; -import com.sap.olingo.jpa.processor.core.filter.JPAOperationConverter; - -/** - * Create a sub query to filter on collection properties e.g. - * CollectionDeeps?$select=ID&$filter=FirstLevel/SecondLevel/Address/any(s:s/TaskID eq 'DEV') or - * CollectionDeeps?$filter=FirstLevel/SecondLevel/Comment/$count eq 2. - * This is done as sub-query instead of a join to have more straightforward way to implement OR or AND conditions - * - * @author Oliver Grande - * - */ -public final class JPACollectionFilterQuery extends JPAAbstractSubQuery { - - public JPACollectionFilterQuery(final OData odata, final JPAServiceDocument sd, final EntityManager em, - final JPAAbstractQuery parent, final List uriResourceParts, final VisitableExpression expression, - final From from, final List groups) throws ODataApplicationException { - - this(odata, sd, em, parent, determineAssociation(parent.jpaEntity, uriResourceParts), expression, from, groups); - } - - public JPACollectionFilterQuery(final OData odata, final JPAServiceDocument sd, final EntityManager em, - final JPAAbstractQuery parent, final JPAAssociationPath associationPath, final VisitableExpression expression, - final From from, final List groups) throws ODataApplicationException { - - super(odata, sd, determineEntityType(parent, associationPath), em, parent, from, associationPath); - // Create a sub-query having the key of the parent as result type - this.subQuery = parent.getQuery().subquery(this.jpaEntity.getKeyType()); - this.filterComplier = new JPAFilterElementComplier(odata, sd, em, jpaEntity, - new JPAOperationConverter(cb, getContext().getOperationConverter()), null, this, expression, association, - groups); - this.aggregationType = getAggregationType(this.filterComplier.getExpressionMember()); - createRoots(this.association); - } - - private static JPAEntityType determineEntityType(final JPAAbstractQuery parent, - final JPAAssociationPath associationPath) { - if (associationPath.getLeaf().isComplex()) - return associationPath.getJoinTable().getEntityType(); - else - return parent.jpaEntity; - } - - private static JPAAssociationPath determineAssociation(final JPAEntityType jpaEntity, - final List uriResourceParts) throws ODataJPAQueryException { - final StringBuilder pathName = new StringBuilder(); - int i = 0; - while (uriResourceParts.get(i) != null - && !(uriResourceParts.get(i) instanceof UriResourceLambdaAny - || uriResourceParts.get(i) instanceof UriResourceLambdaAll - || uriResourceParts.get(i) instanceof UriResourceCount)) { - pathName.append(uriResourceParts.get(i).toString()); - pathName.append(JPAPath.PATH_SEPARATOR); - i++; - } - pathName.deleteCharAt(pathName.lastIndexOf(JPAPath.PATH_SEPARATOR)); - try { - return jpaEntity.getCollectionAttribute(pathName.toString()).asAssociation(); - } catch (final ODataJPAModelException e) { - throw new ODataJPAQueryException(e, HttpStatusCode.INTERNAL_SERVER_ERROR); - } - } - - @SuppressWarnings("unchecked") - @Override - public Subquery getSubQuery(final Subquery childQuery, @Nullable final VisitableExpression expression, - final List>> inPath) throws ODataApplicationException { - - if (this.queryJoinTable != null) { - if (this.aggregationType != null) { - createSubQueryJoinTableAggregation(); - } else { - createSubQueryJoinTable(); - } - } - return (Subquery) this.subQuery; - } - - @Override - public From getRoot() { - assert queryRoot != null; - return queryRoot; - } - - @Override - protected void createRoots(final JPAAssociationPath association) throws ODataJPAQueryException { - if (association.hasJoinTable()) { - if (association.getJoinTable().getEntityType() != null) { - if (aggregationType != null) { - this.queryJoinTable = subQuery.from(from.getJavaType()); - From path = queryJoinTable; - for (int i = 0; i < association.getPath().size() - 1; i++) - path = path.join(association.getPath().get(i).getInternalName()); - this.queryRoot = path.join(association.getLeaf().getInternalName(), JoinType.LEFT); - } else { - this.queryRoot = this.queryJoinTable = subQuery.from(association.getJoinTable() - .getEntityType() - .getTypeClass()); - } - } else { - throw new ODataJPAQueryException(ODataJPAQueryException.MessageKeys.QUERY_PREPARATION_NOT_IMPLEMENTED, - HttpStatusCode.NOT_IMPLEMENTED, association.getAlias()); - } - } else { - throw new ODataJPAQueryException(ODataJPAQueryException.MessageKeys.QUERY_PREPARATION_NOT_IMPLEMENTED, - HttpStatusCode.NOT_IMPLEMENTED, association.getAlias()); - } - } - - private void createSubQueryJoinTable() throws ODataApplicationException { - /* - * SELECT * FROM "BusinessPartner" AS B - * WHERE "Type" = '2' - * AND EXISTS (SELECT "BusinessPartnerID" FROM "Comment" AS C - * WHERE B."ID" = C."BusinessPartnerID" - * AND C."Text" LIKE '%just%') - */ - try { - final List left = association - .getJoinTable() - .getJoinColumns(); - createSelectClauseJoin(subQuery, queryRoot, determineAggregationRightColumns(), false); - final Expression whereCondition = createWhereByAssociation(from, queryJoinTable, left); - subQuery.where(applyAdditionalFilter(whereCondition)); - } catch (final ODataJPAModelException e) { - throw new ODataJPAQueryException(e, HttpStatusCode.INTERNAL_SERVER_ERROR); - } - } - - private void createSubQueryJoinTableAggregation() throws ODataApplicationException { - - try { - createSelectClauseJoin(subQuery, queryRoot, determineAggregationRightColumns(), false); - final Expression whereCondition = createWhereSelfJoin(from, queryJoinTable, jpaEntity); - subQuery.where(applyAdditionalFilter(whereCondition)); - handleAggregation(subQuery, queryJoinTable, determineAggregationLeftColumns()); - } catch (final ODataJPAModelException e) { - throw new ODataJPAQueryException(e, HttpStatusCode.INTERNAL_SERVER_ERROR); - } - } - - @Override - public List>> getLeftPaths() throws ODataJPAIllegalAccessException { - return Collections.emptyList(); - } - -} diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForExistsQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForExistsQuery.java index ccc617e9f..376e43027 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForExistsQuery.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForExistsQuery.java @@ -10,7 +10,6 @@ import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataApplicationException; @@ -18,6 +17,7 @@ import org.apache.olingo.server.api.uri.UriResourceKind; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAOnConditionItem; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; @@ -26,7 +26,7 @@ public class JPANavigationCountForExistsQuery extends JPANavigationCountQuery implements ExistsExpressionValue { - JPANavigationCountForExistsQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType type, + JPANavigationCountForExistsQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType type, final EntityManager em, final JPAAbstractQuery parent, final From from, final JPAAssociationPath association, final Optional claimsProvider, final List keyPredicates) throws ODataApplicationException { diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForInQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForInQuery.java index 3af7c0dcc..c6864a7e4 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForInQuery.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForInQuery.java @@ -9,13 +9,13 @@ import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.uri.UriParameter; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAOnConditionItem; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; @@ -26,7 +26,7 @@ public class JPANavigationCountForInQuery extends JPANavigationCountQuery implements InExpressionValue { private Optional>>> leftPaths; - JPANavigationCountForInQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType type, + JPANavigationCountForInQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType type, final EntityManager em, final JPAAbstractQuery parent, final From from, final JPAAssociationPath association, final Optional claimsProvider, final List keyPredicates) diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountQuery.java index 1faf274c0..7440365fd 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountQuery.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountQuery.java @@ -10,7 +10,6 @@ import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataApplicationException; @@ -20,13 +19,14 @@ import org.apache.olingo.server.api.uri.queryoption.expression.VisitableExpression; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; import com.sap.olingo.jpa.processor.core.api.JPAODataClaimProvider; import com.sap.olingo.jpa.processor.core.exception.ODataJPAQueryException; public abstract class JPANavigationCountQuery extends JPANavigationSubQuery { - JPANavigationCountQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType type, + JPANavigationCountQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType type, final EntityManager em, final JPAAbstractQuery parent, final From from, final JPAAssociationPath association, final Optional claimsProvider, final List keyPredicates) throws ODataApplicationException { diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQuery.java index 2d4f36a5a..9df413aaa 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQuery.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQuery.java @@ -11,16 +11,14 @@ import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.uri.UriParameter; -import org.apache.olingo.server.api.uri.UriResource; -import org.apache.olingo.server.api.uri.UriResourcePartTyped; import org.apache.olingo.server.api.uri.queryoption.expression.VisitableExpression; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAOnConditionItem; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; @@ -29,22 +27,23 @@ public class JPANavigationFilterQuery extends JPANavigationSubQuery implements ExistsExpressionValue { - public JPANavigationFilterQuery(final OData odata, final JPAServiceDocument sd, final UriResource uriResourceItem, + JPANavigationFilterQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType jpaEntityType, final JPAAbstractQuery parent, final EntityManager em, final JPAAssociationPath association, - final From from, final Optional claimsProvider) throws ODataApplicationException { + final From from, final Optional claimsProvider, + final List keyPredicates) throws ODataApplicationException { - super(odata, sd, (EdmEntityType) ((UriResourcePartTyped) uriResourceItem).getType(), em, parent, from, association, - claimsProvider, Utility.determineKeyPredicates(uriResourceItem)); + super(odata, sd, jpaEntityType, em, parent, from, association, + claimsProvider, keyPredicates); this.filterComplier = null; this.aggregationType = null; } - JPANavigationFilterQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType type, + JPANavigationFilterQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType jpaEntityType, final EntityManager em, final JPAAbstractQuery parent, final From from, final JPAAssociationPath association, final Optional claimsProvider, final List keyPredicates) throws ODataApplicationException { - super(odata, sd, type, em, parent, from, association, claimsProvider, keyPredicates); + super(odata, sd, jpaEntityType, em, parent, from, association, claimsProvider, keyPredicates); } /** @@ -64,7 +63,7 @@ public Subquery getSubQuery(final Subquery childQuery, } @SuppressWarnings("unchecked") - protected void createSubQuery(final Subquery childQuery, + protected void createSubQuery(final Subquery childQuery, @Nullable final VisitableExpression expression, final List>> inPath) throws ODataApplicationException { diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryBuilder.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryBuilder.java index 5fdc412fe..799ef9057 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryBuilder.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryBuilder.java @@ -16,15 +16,18 @@ import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourcePartTyped; +import org.apache.olingo.server.api.uri.UriResourceProperty; import org.apache.olingo.server.api.uri.queryoption.expression.Binary; import org.apache.olingo.server.api.uri.queryoption.expression.VisitableExpression; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; import com.sap.olingo.jpa.processor.cb.ProcessorCriteriaBuilder; import com.sap.olingo.jpa.processor.core.api.JPAODataClaimProvider; import com.sap.olingo.jpa.processor.core.exception.ODataJPAFilterException; +import com.sap.olingo.jpa.processor.core.exception.ODataJPAQueryException; import com.sap.olingo.jpa.processor.core.filter.JPACountExpression; import com.sap.olingo.jpa.processor.core.filter.JPAFilterExpression; import com.sap.olingo.jpa.processor.core.filter.JPAMemberOperator; @@ -59,7 +62,7 @@ public class JPANavigationFilterQueryBuilder { private Optional claimsProvider; private List groups; private List keyPredicates; - private EdmEntityType type; + private UriResourcePartTyped uriResource; public JPANavigationFilterQueryBuilder(final CriteriaBuilder cb) { this.cb = cb; @@ -67,6 +70,7 @@ public JPANavigationFilterQueryBuilder(final CriteriaBuilder cb) { public JPANavigationSubQuery build() throws ODataApplicationException { final JPANavigationSubQuery query; + final JPAEntityType type = determineJpaEntityType(); if (expression != null && getAggregationType(expression) != null) { if (asInQuery()) query = new JPANavigationCountForInQuery(odata, sd, @@ -85,6 +89,13 @@ public JPANavigationSubQuery build() throws ODataApplicationException { return query; } + private JPAEntityType determineJpaEntityType() throws ODataJPAQueryException { + if (uriResource instanceof UriResourceProperty) + return determineEntityType(association); + else + return asJPAEntityType((EdmEntityType) uriResource.getType()); + } + public JPANavigationFilterQueryBuilder setOdata(final OData odata) { this.odata = odata; return this; @@ -95,10 +106,11 @@ public JPANavigationFilterQueryBuilder setServiceDocument(final JPAServiceDocume return this; } - public JPANavigationFilterQueryBuilder setUriResourceItem(final UriResource uriResourceItem) - throws ODataApplicationException { - keyPredicates = Utility.determineKeyPredicates(uriResourceItem); - type = (EdmEntityType) ((UriResourcePartTyped) uriResourceItem).getType(); + public JPANavigationFilterQueryBuilder setNavigationInfo(final JPANavigationPropertyInfoAccess navigationInfo) { + this.keyPredicates = navigationInfo.getKeyPredicates(); + this.association = navigationInfo.getAssociationPath(); + this.uriResource = navigationInfo.getUriResource(); + return this; } @@ -112,11 +124,6 @@ public JPANavigationFilterQueryBuilder setEntityManager(final EntityManager em) return this; } - public JPANavigationFilterQueryBuilder setAssociation(final JPAAssociationPath association) { - this.association = association; - return this; - } - public JPANavigationFilterQueryBuilder setExpression(final VisitableExpression expression) { this.expression = expression; return this; @@ -177,4 +184,16 @@ private boolean isNullExpression(final VisitableExpression expression) { return expression instanceof final JPANullExpression nullExpression && NULL.equals(nullExpression.getLiteral().getText()); } + + private JPAEntityType determineEntityType(final JPAAssociationPath associationPath) { + return (JPAEntityType) associationPath.getTargetType(); + } + + private JPAEntityType asJPAEntityType(final EdmEntityType edmEntityType) throws ODataJPAQueryException { + try { + return sd.getEntity(edmEntityType); + } catch (final ODataJPAModelException e) { + throw new ODataJPAQueryException(e, HttpStatusCode.BAD_REQUEST); + } + } } diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationNullQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationNullQuery.java index 1221a1561..a777a12c0 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationNullQuery.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationNullQuery.java @@ -11,7 +11,6 @@ import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataApplicationException; @@ -19,6 +18,7 @@ import org.apache.olingo.server.api.uri.queryoption.expression.VisitableExpression; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAOnConditionItem; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; @@ -36,7 +36,7 @@ */ public final class JPANavigationNullQuery extends JPANavigationSubQuery implements ExistsExpressionValue { - JPANavigationNullQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType type, + JPANavigationNullQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType type, final EntityManager em, final JPAAbstractQuery parent, final From from, final JPAAssociationPath association, final Optional claimsProvider, final List keyPredicates) throws ODataApplicationException { diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationPropertyInfo.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationPropertyInfo.java index 6d849556a..bd1527d2e 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationPropertyInfo.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationPropertyInfo.java @@ -142,7 +142,8 @@ JPAFilterComplier getFilterCompiler() { return fromClause; } - List getKeyPredicates() { + @Override + public List getKeyPredicates() { return keyPredicates; } diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationPropertyInfoAccess.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationPropertyInfoAccess.java index 8f1d6d6fa..5f6fc9d69 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationPropertyInfoAccess.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationPropertyInfoAccess.java @@ -1,5 +1,8 @@ package com.sap.olingo.jpa.processor.core.query; +import java.util.List; + +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.UriResourcePartTyped; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; @@ -10,4 +13,6 @@ public interface JPANavigationPropertyInfoAccess { UriResourcePartTyped getUriResource(); + List getKeyPredicates(); + } \ No newline at end of file diff --git a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationSubQuery.java b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationSubQuery.java index d63d4ea65..876142a63 100644 --- a/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationSubQuery.java +++ b/jpa/odata-jpa-processor/src/main/java/com/sap/olingo/jpa/processor/core/query/JPANavigationSubQuery.java @@ -14,7 +14,6 @@ import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataApplicationException; @@ -24,6 +23,7 @@ import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPADescriptionAttribute; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAElement; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAOnConditionItem; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAPath; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAServiceDocument; @@ -38,11 +38,11 @@ public abstract class JPANavigationSubQuery extends JPAAbstractSubQuery { protected final List keyPredicates; - JPANavigationSubQuery(final OData odata, final JPAServiceDocument sd, final EdmEntityType edmEntityType, + JPANavigationSubQuery(final OData odata, final JPAServiceDocument sd, final JPAEntityType jpaEntity, final EntityManager em, final JPAAbstractQuery parent, final From from, final JPAAssociationPath association, final Optional claimsProvider, final List keyPredicates) throws ODataApplicationException { - super(odata, sd, edmEntityType, em, parent, from, association, claimsProvider); + super(odata, sd, jpaEntity, em, parent, from, association, claimsProvider); this.keyPredicates = keyPredicates; this.subQuery = parent.getQuery().subquery(this.jpaEntity.getKeyType()); this.locale = parent.getLocale(); @@ -52,7 +52,7 @@ public abstract class JPANavigationSubQuery extends JPAAbstractSubQuery { final void buildExpression(final VisitableExpression expression, final List groups) throws ODataApplicationException { this.filterComplier = new JPAFilterElementComplier(odata, sd, em, jpaEntity, new JPAOperationConverter(cb, - getContext().getOperationConverter()), null, this, expression, null, groups); + getContext().getOperationConverter()), null, this, expression, association, groups); createDescriptionJoin(); } diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPAQueryWhereClause.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPAQueryWhereClause.java index ecbf0e7e3..a0836c58d 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPAQueryWhereClause.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/filter/TestJPAQueryWhereClause.java @@ -161,7 +161,7 @@ static Stream getFilterQuery() { arguments("CountNavigationPropertyMultipleHopsNavigations zero", "AdministrativeDivisions?$filter=Parent/Children/$count eq 0", 0), arguments("CountNavigationPropertyJoinTable not zero", "JoinSources?$filter=OneToMany/$count eq 2", 1), - arguments("CountNavigationPropertyJoinTable zero", "JoinSources?$filter=OneToMany/$count eq 0", 1), + arguments("CountCollectionPropertyOne", "Organizations?$select=ID&$filter=Comment/$count ge 1", 2), // To one association null arguments("NavigationPropertyIsNull", "AssociationOneToOneSources?$format=json&$filter=ColumnTarget eq null", 1), diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForExistsQueryTest.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForExistsQueryTest.java index 4df28e6a5..a0a995395 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForExistsQueryTest.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForExistsQueryTest.java @@ -24,7 +24,7 @@ class JPANavigationCountForExistsQueryTest extends JPANavigationCountQueryTest { @Override protected JPANavigationSubQuery createCut() throws ODataApplicationException { - return new JPANavigationCountForExistsQuery(odata, helper.sd, edmEntityType, em, parent, from, association, Optional + return new JPANavigationCountForExistsQuery(odata, helper.sd, jpaEntityType, em, parent, from, association, Optional .of(claimsProvider), Collections.emptyList()); } diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForInQueryTest.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForInQueryTest.java index 0c26a75b0..be9037353 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForInQueryTest.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountForInQueryTest.java @@ -25,7 +25,7 @@ class JPANavigationCountForInQueryTest extends JPANavigationCountQueryTest { @Override protected JPANavigationSubQuery createCut() throws ODataApplicationException { - return new JPANavigationCountForInQuery(odata, helper.sd, edmEntityType, em, parent, from, association, Optional + return new JPANavigationCountForInQuery(odata, helper.sd, jpaEntityType, em, parent, from, association, Optional .of(claimsProvider), Collections.emptyList()); } diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountQueryTest.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountQueryTest.java index 8226d2798..da016535b 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountQueryTest.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationCountQueryTest.java @@ -24,7 +24,6 @@ import jakarta.persistence.criteria.Selection; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.ex.ODataException; @@ -42,6 +41,7 @@ import org.junit.jupiter.api.Test; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; import com.sap.olingo.jpa.processor.core.api.JPAClaimsPair; import com.sap.olingo.jpa.processor.core.api.JPAODataClaimProvider; @@ -69,7 +69,7 @@ abstract class JPANavigationCountQueryTest extends TestBase { protected From from; protected JPAODataClaimProvider claimsProvider; - protected EdmEntityType edmEntityType; + protected JPAEntityType jpaEntityType; @SuppressWarnings("rawtypes") protected CriteriaQuery cq; protected CriteriaBuilder cb; @@ -99,7 +99,6 @@ public void setup() throws ODataException, ODataJPAIllegalAccessException { final UriParameter key = mock(UriParameter.class); when(em.getCriteriaBuilder()).thenReturn(cb); - when(uriResourceItem.getType()).thenReturn(edmEntityType); when(uriResourceItem.getKeyPredicates()).thenReturn(Collections.singletonList(key)); when(parent.getQuery()).thenReturn(cq); when(cq.> subquery(any())).thenReturn(subQuery); @@ -107,17 +106,15 @@ public void setup() throws ODataException, ODataJPAIllegalAccessException { doReturn(BusinessPartnerProtected.class).when(from).getJavaType(); } - protected void createEdmEntityType(final String name) { - edmEntityType = mock(EdmEntityType.class); - when(edmEntityType.getName()).thenReturn(name); - when(edmEntityType.getNamespace()).thenReturn(PUNIT_NAME); + protected void createEdmEntityType(final Class clazz) throws ODataJPAModelException { + jpaEntityType = helper.getJPAEntityType(clazz); } protected abstract Subquery> createSubQuery(); @Test - void testCutExists() throws ODataApplicationException { - createEdmEntityType("BusinessPartnerRoleProtected"); + void testCutExists() throws ODataApplicationException, ODataJPAModelException { + createEdmEntityType(BusinessPartnerRoleProtected.class); cut = createCut(); assertNotNull(cut); } @@ -125,9 +122,9 @@ void testCutExists() throws ODataApplicationException { protected abstract JPANavigationSubQuery createCut() throws ODataApplicationException; @Test - void testGetSubQueryThrowsExceptionWhenChildQueryProvided() throws ODataApplicationException { + void testGetSubQueryThrowsExceptionWhenChildQueryProvided() throws ODataApplicationException, ODataJPAModelException { - createEdmEntityType("BusinessPartnerRoleProtected"); + createEdmEntityType(BusinessPartnerRoleProtected.class); cut = createCut(); assertThrows(ODataJPAQueryException.class, () -> cut.getSubQuery(subQuery, null, Collections.emptyList())); } @@ -138,7 +135,7 @@ void testQueryWithJoinTableAggregateWithClaim() throws ODataApplicationException EdmPrimitiveTypeException, ODataJPAIllegalAccessException { association = helper.getJPAAssociationPath(BusinessPartnerProtected.class, "RolesJoinProtected"); - createEdmEntityType("BusinessPartnerRoleProtected"); + createEdmEntityType(BusinessPartnerRoleProtected.class); final Root queryJoinTable = mock(Root.class); final Root queryRoot = mock(Root.class); final Root parentRoot = mock(Root.class); @@ -183,7 +180,7 @@ void testQueryMultipleJoinColumns() throws ODataApplicationException, ODataJPAMo EdmPrimitiveTypeException, ODataJPAIllegalAccessException { association = helper.getJPAAssociationPath(AdministrativeDivision.class, "Children"); - createEdmEntityType("AdministrativeDivision"); + createEdmEntityType(AdministrativeDivision.class); final Root queryRoot = mock(Root.class); when(subQuery.from(AdministrativeDivision.class)).thenReturn(queryRoot); @@ -211,7 +208,7 @@ void testQueryOneJoinColumnsWithClaims() throws ODataApplicationException, OData EdmPrimitiveTypeException, ODataJPAIllegalAccessException { association = helper.getJPAAssociationPath(BusinessPartnerProtected.class, "RolesProtected"); - createEdmEntityType("BusinessPartnerRoleProtected"); + createEdmEntityType(BusinessPartnerRoleProtected.class); final Path roleCategoryPath = mock(Path.class); final Root queryRoot = mock(Root.class); @@ -237,8 +234,9 @@ void testQueryOneJoinColumnsWithClaims() throws ODataApplicationException, OData } @Test - void testGetLeftOnEarlyAccess() throws ODataApplicationException, ODataJPAIllegalAccessException { - createEdmEntityType("BusinessPartnerRoleProtected"); + void testGetLeftOnEarlyAccess() throws ODataApplicationException, ODataJPAIllegalAccessException, + ODataJPAModelException { + createEdmEntityType(BusinessPartnerRoleProtected.class); cut = createCut(); assertLeftEarlyAccess(); } diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryBuilderTest.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryBuilderTest.java index 9301b22fe..3e6fcd8f7 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryBuilderTest.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryBuilderTest.java @@ -31,6 +31,7 @@ import org.apache.olingo.server.api.uri.UriResourceCount; import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourceNavigation; +import org.apache.olingo.server.api.uri.UriResourcePartTyped; import org.apache.olingo.server.api.uri.queryoption.expression.Literal; import org.apache.olingo.server.api.uri.queryoption.expression.VisitableExpression; import org.junit.jupiter.api.BeforeEach; @@ -49,6 +50,7 @@ import com.sap.olingo.jpa.processor.core.api.JPAODataRequestContextAccess; import com.sap.olingo.jpa.processor.core.database.JPAODataDatabaseOperations; import com.sap.olingo.jpa.processor.core.exception.ODataJPAFilterException; +import com.sap.olingo.jpa.processor.core.exception.ODataJPAQueryException; import com.sap.olingo.jpa.processor.core.filter.JPACountExpression; import com.sap.olingo.jpa.processor.core.filter.JPANullExpression; import com.sap.olingo.jpa.processor.core.testmodel.Person; @@ -56,7 +58,7 @@ class JPANavigationFilterQueryBuilderTest { private JPAServiceDocument sd; private EntityManager em; - private UriResource uriResourceItem; + private UriResourcePartTyped uriResourceItem; private JPAAbstractQuery parent; private JPAAssociationPath association; private VisitableExpression expression; @@ -65,6 +67,7 @@ class JPANavigationFilterQueryBuilderTest { private List groups; private CriteriaBuilder cb; + private JPANavigationPropertyInfoAccess navigationInfo; private JPAODataRequestContextAccess context; private JPAODataDatabaseOperations dbOperations; private JPAEntityType et; @@ -80,12 +83,13 @@ class JPANavigationFilterQueryBuilderTest { void setup() throws ODataJPAModelException { sd = mock(JPAServiceDocument.class); em = mock(EntityManager.class); - uriResourceItem = mock(UriResource.class); + uriResourceItem = mock(UriResourcePartTyped.class); parent = mock(JPAAbstractQuery.class); association = mock(JPAAssociationPath.class); from = mock(From.class); claimsProvider = mock(JPAODataClaimProvider.class); + navigationInfo = mock(JPANavigationPropertyInfoAccess.class); uriResourceItem = mock(UriResourceNavigation.class); context = mock(JPAODataRequestContextAccess.class); dbOperations = mock(JPAODataDatabaseOperations.class); @@ -108,6 +112,8 @@ void setup() throws ODataJPAModelException { doReturn(query).when(parent).getQuery(); when(query.subquery(Integer.class)).thenReturn(subQuery); when(subQuery.from(Person.class)).thenReturn(queryRoot); + when(navigationInfo.getAssociationPath()).thenReturn(association); + when(navigationInfo.getUriResource()).thenReturn(uriResourceItem); } @Test @@ -117,10 +123,9 @@ void testCreatesFilterQuery() throws ODataApplicationException, ODataJPAModelExc cut.setOdata(o) .setServiceDocument(sd) .setEntityManager(em) - .setUriResourceItem(uriResourceItem) + .setNavigationInfo(navigationInfo) .setParent(parent) .setFrom(from) - .setAssociation(association) .setClaimsProvider(claimsProvider) .setExpression(expression) .setGroups(groups); @@ -153,10 +158,9 @@ void testCreatesCountQuery(final VisitableExpression exp) throws ODataApplicatio cut.setOdata(o) .setServiceDocument(sd) .setEntityManager(em) - .setUriResourceItem(uriResourceItem) + .setNavigationInfo(navigationInfo) .setParent(parent) .setFrom(from) - .setAssociation(association) .setClaimsProvider(claimsProvider) .setExpression(exp) .setGroups(groups); @@ -189,10 +193,9 @@ void testCreatesNullQuery(final VisitableExpression exp) throws ODataApplication cut.setOdata(o) .setServiceDocument(sd) .setEntityManager(em) - .setUriResourceItem(uriResourceItem) + .setNavigationInfo(navigationInfo) .setParent(parent) .setFrom(from) - .setAssociation(association) .setClaimsProvider(claimsProvider) .setExpression(exp) .setGroups(groups); @@ -229,34 +232,37 @@ void testAsExistsQueryForProcessorCriteriaBuilderNotCount() throws ODataJPAFilte @Test void testAsInQueryTrueForCriteriaBuilderAssociationOneAttribute() throws ODataJPAModelException, - ODataJPAFilterException { + ODataJPAFilterException, ODataJPAQueryException { final JPAAssociationPath associationPath = mock(JPAAssociationPath.class); final JPAOnConditionItem onCondition = mock(JPAOnConditionItem.class); when(associationPath.getJoinColumnsList()).thenReturn(Collections.singletonList(onCondition)); - cut.setAssociation(associationPath); + when(navigationInfo.getAssociationPath()).thenReturn(associationPath); + cut.setNavigationInfo(navigationInfo); cut.setExpression(buildCountFromCountExpression()); assertTrue(cut.asInQuery()); } @Test void testAsInQueryFalseForCriteriaBuilderAssociationTwoAttribute() throws ODataJPAModelException, - ODataJPAFilterException { + ODataJPAFilterException, ODataJPAQueryException { final JPAAssociationPath associationPath = mock(JPAAssociationPath.class); final JPAOnConditionItem onCondition = mock(JPAOnConditionItem.class); when(associationPath.getJoinColumnsList()).thenReturn(Arrays.asList(onCondition, onCondition)); - cut.setAssociation(associationPath); + when(navigationInfo.getAssociationPath()).thenReturn(associationPath); + cut.setNavigationInfo(navigationInfo); cut.setExpression(buildCountFromCountExpression()); assertFalse(cut.asInQuery()); } @Test - void testAsInQueryRethrowsException() throws ODataJPAFilterException, ODataJPAModelException { + void testAsInQueryRethrowsException() throws ODataJPAFilterException, ODataJPAModelException, ODataJPAQueryException { final JPAAssociationPath associationPath = mock(JPAAssociationPath.class); when(associationPath.getJoinColumnsList()).thenThrow(ODataJPAModelException.class); - cut.setAssociation(associationPath); + when(navigationInfo.getAssociationPath()).thenReturn(associationPath); + cut.setNavigationInfo(navigationInfo); assertThrows(ODataJPAFilterException.class, () -> cut.asInQuery()); } diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryTest.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryTest.java index aec06810b..30411acc4 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryTest.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationFilterQueryTest.java @@ -19,7 +19,6 @@ import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.ex.ODataException; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.ODataApplicationException; @@ -29,6 +28,7 @@ import org.junit.jupiter.api.Test; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.processor.core.api.JPAClaimsPair; import com.sap.olingo.jpa.processor.core.api.JPAODataClaimProvider; import com.sap.olingo.jpa.processor.core.exception.ODataJPAIllegalAccessException; @@ -50,7 +50,7 @@ class JPANavigationFilterQueryTest extends TestBase { protected Root queryJoinTable; protected Root queryRoot; protected JPAODataClaimProvider claimsProvider; - protected EdmEntityType edmEntityType; + protected JPAEntityType jpaEntityType; @SuppressWarnings("rawtypes") protected CriteriaQuery cq; protected CriteriaBuilder cb; @@ -66,7 +66,7 @@ public void setup() throws ODataException, ODataJPAIllegalAccessException { claimsProvider = mock(JPAODataClaimProvider.class); odata = OData.newInstance(); uriResourceItem = mock(UriResourceNavigation.class); - edmEntityType = mock(EdmEntityType.class); + jpaEntityType = helper.getJPAEntityType(BusinessPartnerRoleProtected.class); cq = mock(CriteriaQuery.class); cb = mock(CriteriaBuilder.class); // emf.getCriteriaBuilder(); subQuery = mock(Subquery.class); @@ -77,10 +77,7 @@ public void setup() throws ODataException, ODataJPAIllegalAccessException { final UriParameter key = mock(UriParameter.class); when(em.getCriteriaBuilder()).thenReturn(cb); - when(uriResourceItem.getType()).thenReturn(edmEntityType); when(uriResourceItem.getKeyPredicates()).thenReturn(Collections.singletonList(key)); - when(edmEntityType.getName()).thenReturn("BusinessPartnerRoleProtected"); - when(edmEntityType.getNamespace()).thenReturn(PUNIT_NAME); when(parent.getQuery()).thenReturn(cq); when(cq.subquery(any())).thenReturn(subQuery); when(subQuery.from(JoinPartnerRoleRelation.class)).thenReturn(queryJoinTable); @@ -90,8 +87,8 @@ public void setup() throws ODataException, ODataJPAIllegalAccessException { } protected JPAAbstractSubQuery createCut() throws ODataApplicationException { - return new JPANavigationFilterQuery(odata, helper.sd, uriResourceItem, - parent, em, association, from, Optional.of(claimsProvider)); + return new JPANavigationFilterQuery(odata, helper.sd, jpaEntityType, + parent, em, association, from, Optional.of(claimsProvider), Collections.emptyList()); } @Test diff --git a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationNullQueryTest.java b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationNullQueryTest.java index 75b5a0b93..ae612b236 100644 --- a/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationNullQueryTest.java +++ b/jpa/odata-jpa-processor/src/test/java/com/sap/olingo/jpa/processor/core/query/JPANavigationNullQueryTest.java @@ -20,7 +20,6 @@ import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.Subquery; -import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.ex.ODataException; @@ -36,6 +35,7 @@ import org.junit.jupiter.api.Test; import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAAssociationPath; +import com.sap.olingo.jpa.metadata.core.edm.mapper.api.JPAEntityType; import com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException; import com.sap.olingo.jpa.processor.core.api.JPAClaimsPair; import com.sap.olingo.jpa.processor.core.api.JPAODataClaimProvider; @@ -60,7 +60,7 @@ class JPANavigationNullQueryTest extends TestBase { private From from; private Root queryRoot; private JPAODataClaimProvider claimsProvider; - private EdmEntityType edmEntityType; + private JPAEntityType jpaEntityType; @SuppressWarnings("rawtypes") private CriteriaQuery cq; private CriteriaBuilder cb; @@ -77,7 +77,7 @@ public void setup() throws ODataException, ODataJPAIllegalAccessException { claimsProvider = mock(JPAODataClaimProvider.class); odata = OData.newInstance(); uriResourceItem = mock(UriResourceNavigation.class); - edmEntityType = mock(EdmEntityType.class); + jpaEntityType = helper.getJPAEntityType(BusinessPartnerProtected.class); cq = mock(CriteriaQuery.class); cb = mock(CriteriaBuilder.class); // emf.getCriteriaBuilder(); subQuery = mock(Subquery.class); @@ -88,10 +88,8 @@ public void setup() throws ODataException, ODataJPAIllegalAccessException { final UriParameter key = mock(UriParameter.class); when(em.getCriteriaBuilder()).thenReturn(cb); - when(uriResourceItem.getType()).thenReturn(edmEntityType); + // when(uriResourceItem.getType()).thenReturn(jpaEntityType); when(uriResourceItem.getKeyPredicates()).thenReturn(Collections.singletonList(key)); - when(edmEntityType.getName()).thenReturn("BusinessPartnerProtected"); - when(edmEntityType.getNamespace()).thenReturn(PUNIT_NAME); when(parent.getQuery()).thenReturn(cq); when(cq.subquery(any())).thenReturn(subQuery); when(subQuery.from(BusinessPartnerProtected.class)).thenReturn(queryRoot); @@ -102,7 +100,7 @@ public void setup() throws ODataException, ODataJPAIllegalAccessException { @Test void testCutExists() throws ODataApplicationException { - cut = new JPANavigationNullQuery(odata, helper.sd, edmEntityType, em, parent, from, association, Optional.of( + cut = new JPANavigationNullQuery(odata, helper.sd, jpaEntityType, em, parent, from, association, Optional.of( claimsProvider), Collections.emptyList()); assertNotNull(cut); } @@ -110,7 +108,7 @@ void testCutExists() throws ODataApplicationException { @Test void testGetSubQueryThrowsExceptionWhenChildQueryProvided() throws ODataApplicationException { - cut = new JPANavigationNullQuery(odata, helper.sd, edmEntityType, em, parent, from, association, Optional.of( + cut = new JPANavigationNullQuery(odata, helper.sd, jpaEntityType, em, parent, from, association, Optional.of( claimsProvider), Collections.emptyList()); assertThrows(ODataJPAQueryException.class, () -> cut.getSubQuery(subQuery, null, Collections.emptyList())); } @@ -142,7 +140,7 @@ void testJoinQueryAggregateWithClaim() throws ODataApplicationException, ODataJP when(from.get("businessPartnerID")).thenReturn(idPath); when(cb.equal(idPath, idPath)).thenReturn(equalExpression1); - cut = new JPANavigationNullQuery(odata, helper.sd, edmEntityType, em, parent, from, association, Optional.of( + cut = new JPANavigationNullQuery(odata, helper.sd, jpaEntityType, em, parent, from, association, Optional.of( claimsProvider), Collections.emptyList()); cut.buildExpression(expression, Collections.emptyList()); diff --git a/jpa/odata-jpa-test/src/main/java/com/sap/olingo/jpa/processor/core/testmodel/BusinessPartnerWithGroups.java b/jpa/odata-jpa-test/src/main/java/com/sap/olingo/jpa/processor/core/testmodel/BusinessPartnerWithGroups.java index 6e1f6988c..5b5777e00 100644 --- a/jpa/odata-jpa-test/src/main/java/com/sap/olingo/jpa/processor/core/testmodel/BusinessPartnerWithGroups.java +++ b/jpa/odata-jpa-test/src/main/java/com/sap/olingo/jpa/processor/core/testmodel/BusinessPartnerWithGroups.java @@ -9,7 +9,6 @@ import java.util.List; import jakarta.persistence.AssociationOverride; -import jakarta.persistence.AssociationOverrides; import jakarta.persistence.CascadeType; import jakarta.persistence.CollectionTable; import jakarta.persistence.Column; @@ -96,15 +95,13 @@ public class BusinessPartnerWithGroups implements KeyAccess { protected CommunicationData communicationData; @Embedded - @AssociationOverrides({ - @AssociationOverride(name = "countryName", - joinColumns = @JoinColumn(referencedColumnName = "\"Address.Country\"", name = "\"ISOCode\"")), - @AssociationOverride(name = "regionName", - joinColumns = { - @JoinColumn(referencedColumnName = "\"Address.RegionCodePublisher\"", name = "\"CodePublisher\""), - @JoinColumn(referencedColumnName = "\"Address.RegionCodeID\"", name = "\"CodeID\""), - @JoinColumn(referencedColumnName = "\"Address.Region\"", name = "\"DivisionCode\"") }) - }) + @AssociationOverride(name = "countryName", + joinColumns = @JoinColumn(referencedColumnName = "\"Address.Country\"", name = "\"ISOCode\"")) + @AssociationOverride(name = "regionName", + joinColumns = { + @JoinColumn(referencedColumnName = "\"Address.RegionCodePublisher\"", name = "\"CodePublisher\""), + @JoinColumn(referencedColumnName = "\"Address.RegionCodeID\"", name = "\"CodeID\""), + @JoinColumn(referencedColumnName = "\"Address.Region\"", name = "\"DivisionCode\"") }) private final PostalAddressDataWithGroup address = new PostalAddressDataWithGroup(); @Embedded diff --git a/jpa/odata-jpa-test/src/main/resources/db/migration/V1_0__olingo.sql b/jpa/odata-jpa-test/src/main/resources/db/migration/V1_0__olingo.sql index ba17f73e3..d4a3485f5 100644 --- a/jpa/odata-jpa-test/src/main/resources/db/migration/V1_0__olingo.sql +++ b/jpa/odata-jpa-test/src/main/resources/db/migration/V1_0__olingo.sql @@ -701,7 +701,8 @@ CREATE TABLE "Comment" ( PRIMARY KEY ("BusinessPartnerID", "Order")); insert into "Comment" values( '1', 1, 'This is just a test'); -insert into "Comment" values( '1', 3, 'This is another test'); +insert into "Comment" values( '1', 3, 'This is another test'); +insert into "Comment" values( '7', 1, 'This is another test'); insert into "Comment" values( '501', 3, 'This is another test'); insert into "Comment" values( '502', 3, 'This is another test'); insert into "Comment" values( '502', 4, 'This is also test'); diff --git a/jpa/pom.xml b/jpa/pom.xml index 5bf6ab269..18fe629b6 100644 --- a/jpa/pom.xml +++ b/jpa/pom.xml @@ -13,7 +13,7 @@ 17 17 3.8.0 - 4.10.0 + 4.9.0 2.14.1 1.7.1 4.3.0