HHH-14982 Fix SQL Errors, add javadoc and extend spatial criteria tests

This commit is contained in:
Marco Belladelli 2022-11-29 09:28:03 +01:00 committed by Christian Beikov
parent 3b14107c49
commit 3abc8c940a
6 changed files with 490 additions and 58 deletions

View File

@ -13,61 +13,281 @@ import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* An extended {@link HibernateCriteriaBuilder} with spatial functionality
*
* @author Marco Belladelli
*/
public interface SpatialCriteriaBuilder<T> extends HibernateCriteriaBuilder {
/**
* Create a predicate for testing the arguments for "spatially equal" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
*
* @return "spatially equal" predicate
*/
Predicate eq(Expression<? extends T> geometry1, Expression<? extends T> geometry2);
/**
* Create a predicate for testing the arguments for "spatially equal" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
*
* @return "spatially equal" predicate
*
* @see #eq(Expression, Expression)
*/
Predicate eq(Expression<? extends T> geometry1, T geometry2);
/**
* Create a predicate for testing the arguments for "spatially within" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
*
* @return "spatially within" predicate
*/
Predicate within(Expression<? extends T> geometry1, Expression<? extends T> geometry2);
/**
* Create a predicate for testing the arguments for "spatially within" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
*
* @return "spatially within" predicate
*
* @see #within(Expression, Expression)
*/
Predicate within(Expression<? extends T> geometry1, T geometry2);
/**
* Create a predicate for testing the arguments for "spatially contains" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
*
* @return "spatially contains" predicate
*/
Predicate contains(Expression<? extends T> geometry1, Expression<? extends T> geometry2);
/**
* Create a predicate for testing the arguments for "spatially contains" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
*
* @return "spatially contains" predicate
*
* @see #contains(Expression, Expression)
*/
Predicate contains(Expression<? extends T> geometry1, T geometry2);
/**
* Create a predicate for testing the arguments for "spatially crosses" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
*
* @return "spatially crosses" predicate
*/
Predicate crosses(Expression<? extends T> geometry1, Expression<? extends T> geometry2);
/**
* Create a predicate for testing the arguments for "spatially crosses" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
*
* @return "spatially crosses" predicate
*
* @see #crosses(Expression, Expression)
*/
Predicate crosses(Expression<? extends T> geometry1, T geometry2);
/**
* Create a predicate for testing the arguments for "spatially disjoint" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
*
* @return "spatially disjoint" predicate
*/
Predicate disjoint(Expression<? extends T> geometry1, Expression<? extends T> geometry2);
/**
* Create a predicate for testing the arguments for "spatially disjoint" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
*
* @return "spatially disjoint" predicate
*
* @see #disjoint(Expression, Expression)
*/
Predicate disjoint(Expression<? extends T> geometry1, T geometry2);
/**
* Create a predicate for testing the arguments for "spatially intersects" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
*
* @return "spatially intersects" predicate
*/
Predicate intersects(Expression<? extends T> geometry1, Expression<? extends T> geometry2);
/**
* Create a predicate for testing the arguments for "spatially intersects" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
*
* @return "spatially intersects" predicate
*
* @see #intersects(Expression, Expression)
*/
Predicate intersects(Expression<? extends T> geometry1, T geometry2);
/**
* Create a predicate for testing the arguments for "spatially overlaps" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
*
* @return "spatially overlaps" predicate
*/
Predicate overlaps(Expression<? extends T> geometry1, Expression<? extends T> geometry2);
/**
* Create a predicate for testing the arguments for "spatially overlaps" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
*
* @return "spatially overlaps" predicate
*
* @see #overlaps(Expression, Expression)
*/
Predicate overlaps(Expression<? extends T> geometry1, T geometry2);
/**
* Create a predicate for testing the arguments for "spatially touches" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
*
* @return "spatially touches" predicate
*/
Predicate touches(Expression<? extends T> geometry1, Expression<? extends T> geometry2);
/**
* Create a predicate for testing the arguments for "spatially touches" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
*
* @return "spatially touches" predicate
*
* @see #touches(Expression, Expression)
*/
Predicate touches(Expression<? extends T> geometry1, T geometry2);
/**
* Create a predicate for testing the arguments for "distance within" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
* @param distance distance expression
*
* @return "distance within" predicate
*/
Predicate distanceWithin(
Expression<? extends T> geometry1,
Expression<? extends T> geometry2,
Expression<Double> distance);
/**
* Create a predicate for testing the arguments for "distance within" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
* @param distance distance expression
*
* @return "distance within" predicate
*
* @see #distanceWithin(Expression, Expression, Expression)
*/
Predicate distanceWithin(Expression<? extends T> geometry1, T geometry2, Expression<Double> distance);
/**
* Create a predicate for testing the arguments for "distance within" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry value
* @param distance distance value
*
* @return "distance within" predicate
*
* @see #distanceWithin(Expression, Expression, Expression)
*/
Predicate distanceWithin(Expression<? extends T> geometry1, T geometry2, double distance);
/**
* Create a predicate for testing the arguments for "distance within" constraint.
*
* @param geometry1 geometry expression
* @param geometry2 geometry expression
* @param distance distance value
*
* @return "distance within" predicate
*
* @see #distanceWithin(Expression, Expression, Expression)
*/
Predicate distanceWithin(
Expression<? extends T> geometry1,
Expression<? extends T> geometry2,
double distance);
/**
* Create a predicate for testing the arguments for "having srid" constraint.
*
* @param geometry geometry expression
* @param srid SRID expression
*
* @return "having srid" predicate
*/
Predicate havingSRID(Expression<? extends T> geometry, Expression<Integer> srid);
/**
* Create a predicate for testing the arguments for "having srid" constraint.
*
* @param geometry geometry expression
* @param srid SRID expression
*
* @return "having srid" predicate
*
* @see #havingSRID(Expression, Expression)
*/
Predicate havingSRID(Expression<? extends T> geometry, int srid);
Predicate isEmpty(CriteriaBuilder criteriaBuilder, Expression<? extends T> geometry);
/**
* Create a predicate for testing the arguments for "is empty" constraint.
*
* @param geometry geometry expression
*
* @return "is empty" predicate
*/
Predicate isGeometryEmpty(Expression<? extends T> geometry);
Predicate isNotEmpty(CriteriaBuilder criteriaBuilder, Expression<? extends T> geometry);
/**
* Create a predicate for testing the arguments for "is not empty" constraint.
*
* @param geometry geometry expression
*
* @return "is not empty" predicate
*/
Predicate isGeometryNotEmpty(Expression<? extends T> geometry);
}

View File

@ -36,7 +36,7 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
@Override
public Predicate eq(Expression<? extends T> geometry1, Expression<? extends T> geometry2) {
return isTrue( function( ST_EQUALS.name(), boolean.class, geometry1, geometry2 ) );
return equal( function( ST_EQUALS.name(), boolean.class, geometry1, geometry2 ), true );
}
@Override
@ -46,7 +46,7 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
@Override
public Predicate within(Expression<? extends T> geometry1, Expression<? extends T> geometry2) {
return isTrue( function( ST_WITHIN.name(), boolean.class, geometry1, geometry2 ) );
return equal( function( ST_WITHIN.name(), boolean.class, geometry1, geometry2 ), true );
}
@Override
@ -56,7 +56,7 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
@Override
public Predicate contains(Expression<? extends T> geometry1, Expression<? extends T> geometry2) {
return isTrue( function( ST_CONTAINS.name(), boolean.class, geometry1, geometry2 ) );
return equal( function( ST_CONTAINS.name(), boolean.class, geometry1, geometry2 ), true );
}
@Override
@ -66,7 +66,7 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
@Override
public Predicate crosses(Expression<? extends T> geometry1, Expression<? extends T> geometry2) {
return isTrue( function( ST_CROSSES.name(), boolean.class, geometry1, geometry2 ) );
return equal( function( ST_CROSSES.name(), boolean.class, geometry1, geometry2 ), true );
}
@Override
@ -76,7 +76,7 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
@Override
public Predicate disjoint(Expression<? extends T> geometry1, Expression<? extends T> geometry2) {
return isTrue( function( ST_DISJOINT.name(), boolean.class, geometry1, geometry2 ) );
return equal( function( ST_DISJOINT.name(), boolean.class, geometry1, geometry2 ), true );
}
@Override
@ -86,7 +86,7 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
@Override
public Predicate intersects(Expression<? extends T> geometry1, Expression<? extends T> geometry2) {
return isTrue( function( ST_INTERSECTS.name(), boolean.class, geometry1, geometry2 ) );
return equal( function( ST_INTERSECTS.name(), boolean.class, geometry1, geometry2 ), true );
}
@Override
@ -96,7 +96,7 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
@Override
public Predicate overlaps(Expression<? extends T> geometry1, Expression<? extends T> geometry2) {
return isTrue( function( ST_OVERLAPS.name(), boolean.class, geometry1, geometry2 ) );
return equal( function( ST_OVERLAPS.name(), boolean.class, geometry1, geometry2 ), true );
}
@Override
@ -106,7 +106,7 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
@Override
public Predicate touches(Expression<? extends T> geometry1, Expression<? extends T> geometry2) {
return isTrue( function( ST_TOUCHES.name(), boolean.class, geometry1, geometry2 ) );
return equal( function( ST_TOUCHES.name(), boolean.class, geometry1, geometry2 ), true );
}
@Override
@ -119,7 +119,10 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
Expression<? extends T> geometry1,
Expression<? extends T> geometry2,
Expression<Double> distance) {
return isTrue( function( SpatialFunction.dwithin.toString(), boolean.class, geometry1, geometry2, distance ) );
return equal(
function( SpatialFunction.dwithin.toString(), boolean.class, geometry1, geometry2, distance ),
true
);
}
@Override
@ -151,12 +154,12 @@ public abstract class SpatialCriteriaBuilderImpl<T> extends HibernateCriteriaBui
}
@Override
public Predicate isEmpty(CriteriaBuilder criteriaBuilder, Expression<? extends T> geometry) {
return isTrue( function( SpatialFunction.isempty.toString(), boolean.class, geometry ) );
public Predicate isGeometryEmpty(Expression<? extends T> geometry) {
return equal( function( SpatialFunction.isempty.toString(), boolean.class, geometry ), true );
}
@Override
public Predicate isNotEmpty(CriteriaBuilder criteriaBuilder, Expression<? extends T> geometry) {
return isEmpty( criteriaBuilder, geometry ).not();
public Predicate isGeometryNotEmpty(Expression<? extends T> geometry) {
return isGeometryEmpty( geometry ).not();
}
}

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.integration.criteria;
import java.util.stream.Stream;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.spatial.HibernateSpatialConfigurationSettings;
import org.hibernate.spatial.testing.IsSupportedBySpatial;
import org.hibernate.spatial.testing.dialects.PredicateRegexes;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.Setting;
/**
* Test SpatialCriteria queries using geometric parameter binding
*
* @author Marco Belladelli
*/
@RequiresDialectFeature(feature = IsSupportedBySpatial.class)
@ServiceRegistry(settings = {
@Setting(name = AvailableSettings.CRITERIA_VALUE_HANDLING_MODE, value = "BIND"),
@Setting(name = HibernateSpatialConfigurationSettings.ORACLE_OGC_STRICT, value = "true")
})
@SessionFactory
public class SpatialCriteriaBindingModeTest extends SpatialCriteriaTest {
@Override
public Stream<PredicateRegexes.PredicateRegex> getTestRegexes() {
return super.predicateRegexes.bindingModeRegexes();
}
}

View File

@ -0,0 +1,40 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.integration.criteria;
import java.util.stream.Stream;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.spatial.HibernateSpatialConfigurationSettings;
import org.hibernate.spatial.testing.IsSupportedBySpatial;
import org.hibernate.spatial.testing.dialects.PredicateRegexes;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.Setting;
import org.hibernate.testing.orm.junit.SkipForDialect;
/**
* Test SpatialCriteria queries using geometric parameter inlining
*
* @author Marco Belladelli
*/
@RequiresDialectFeature(feature = IsSupportedBySpatial.class)
@ServiceRegistry(settings = {
@Setting(name = AvailableSettings.CRITERIA_VALUE_HANDLING_MODE, value = "INLINE"),
@Setting(name = HibernateSpatialConfigurationSettings.ORACLE_OGC_STRICT, value = "true")
})
@SessionFactory
@SkipForDialect(dialectClass = OracleDialect.class, majorVersion = 11, reason = "See https://hibernate.atlassian.net/browse/HHH-15669")
public class SpatialCriteriaInlineModeTest extends SpatialCriteriaTest {
@Override
public Stream<PredicateRegexes.PredicateRegex> getTestRegexes() {
return super.predicateRegexes.inlineModeRegexes();
}
}

View File

@ -0,0 +1,60 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.integration.criteria;
import java.util.List;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.query.Query;
import org.hibernate.spatial.criteria.GeolatteSpatialCriteriaBuilder;
import org.hibernate.spatial.criteria.JTSSpatialCriteriaBuilder;
import org.hibernate.spatial.testing.IsSupportedBySpatial;
import org.hibernate.spatial.testing.SpatialSessionFactoryAware;
import org.hibernate.spatial.testing.SpatialTestBase;
import org.hibernate.spatial.testing.datareader.TestSupport;
import org.hibernate.spatial.testing.domain.GeomEntity;
import org.hibernate.spatial.testing.domain.JtsGeomEntity;
import org.hibernate.spatial.testing.domain.SpatialDomainModel;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.junit.jupiter.api.Test;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.geolatte.geom.G2D;
import org.geolatte.geom.Polygon;
import static org.geolatte.geom.builder.DSL.g;
import static org.geolatte.geom.builder.DSL.polygon;
import static org.geolatte.geom.builder.DSL.ring;
import static org.geolatte.geom.crs.CoordinateReferenceSystems.WGS84;
import static org.junit.jupiter.api.Assertions.assertFalse;
@DomainModel(modelDescriptorClasses = SpatialDomainModel.class)
@SessionFactory
@RequiresDialectFeature(feature = IsSupportedBySpatial.class)
@SkipForDialect(dialectClass = OracleDialect.class, majorVersion = 11, reason = "See https://hibernate.atlassian.net/browse/HHH-15669")
public class SpatialCriteriaSmokeTest extends SpatialSessionFactoryAware {
@Test
public void test() {
scope.inTransaction( (session) -> {
GeolatteSpatialCriteriaBuilder cb = session.getCriteriaBuilder()
.unwrap( GeolatteSpatialCriteriaBuilder.class );
CriteriaQuery<GeomEntity> cr = cb.createQuery( GeomEntity.class );
Root<GeomEntity> root = cr.from( GeomEntity.class );
cr.select( root ).where( cb.intersects(
root.get( "geom" ),
filterGeometry
) );
List<GeomEntity> results = session.createQuery( cr ).getResultList();
} );
}
}

View File

@ -6,75 +6,147 @@
*/
package org.hibernate.spatial.integration.criteria;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.query.Query;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.spatial.criteria.GeolatteSpatialCriteriaBuilder;
import org.hibernate.spatial.criteria.JTSSpatialCriteriaBuilder;
import org.hibernate.spatial.testing.IsSupportedBySpatial;
import org.hibernate.spatial.criteria.SpatialCriteriaBuilder;
import org.hibernate.spatial.integration.Model;
import org.hibernate.spatial.testing.HSReflectionUtil;
import org.hibernate.spatial.testing.SpatialTestBase;
import org.hibernate.spatial.testing.datareader.TestSupport;
import org.hibernate.spatial.testing.domain.GeomEntity;
import org.hibernate.spatial.testing.domain.JtsGeomEntity;
import org.hibernate.spatial.testing.domain.SpatialDomainModel;
import org.hibernate.spatial.testing.dialects.PredicateRegexes;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.junit.jupiter.api.Test;
import org.hibernate.testing.jdbc.SQLStatementInspector;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.function.Executable;
import org.junit.platform.commons.JUnitException;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Root;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@DomainModel(modelDescriptorClasses = SpatialDomainModel.class)
@SessionFactory
@RequiresDialectFeature(feature = IsSupportedBySpatial.class)
@SkipForDialect(dialectClass = OracleDialect.class, majorVersion = 11, reason = "See https://hibernate.atlassian.net/browse/HHH-15669")
public class SpatialCriteriaTest extends SpatialTestBase {
/**
* Abstract test factory for most {@link SpatialCriteriaBuilder}
* predicate functions
*
* @author Marco Belladelli
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
abstract public class SpatialCriteriaTest extends SpatialTestBase {
@Override
public TestSupport.TestDataPurpose purpose() {
return TestSupport.TestDataPurpose.SpatialFunctionsData;
}
@Test
public void testJtsSpatialCriteriaIntersects() {
scope.inTransaction( (session) -> {
JTSSpatialCriteriaBuilder cb = session.getCriteriaBuilder().unwrap( JTSSpatialCriteriaBuilder.class );
abstract public Stream<PredicateRegexes.PredicateRegex> getTestRegexes();
CriteriaQuery<JtsGeomEntity> cr = cb.createQuery( JtsGeomEntity.class );
Root<JtsGeomEntity> root = cr.from( JtsGeomEntity.class );
cr.select( root ).where( cb.intersects(
root.get( "geom" ),
org.geolatte.geom.jts.JTS.to( filterGeometry )
) );
@TestFactory
public Stream<DynamicTest> testFactory() {
return
getTestRegexes()
.flatMap( rp -> Stream.of(
new Args( rp.predicate, rp.regex, Model.GLMODEL ),
new Args( rp.predicate, rp.regex, Model.JTSMODEL )
) )
.map( args -> DynamicTest.dynamicTest(
displayName( args ),
testPredicate(
args.method,
args.regex,
args.model
)
) );
}
Query<JtsGeomEntity> query = session.createQuery( cr );
List<JtsGeomEntity> results = query.getResultList();
assertFalse( results.isEmpty() );
public Executable testPredicate(final String key, final String regex, Model model) {
return () -> scope.inSession( session -> {
SQLStatementInspector inspector = SQLStatementInspector.extractFromSession( session );
inspector.clear();
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
// unwrap CriteriaBuilder based on model
Class spatialCriteriaBuilderClass = model == Model.JTSMODEL ?
JTSSpatialCriteriaBuilder.class :
GeolatteSpatialCriteriaBuilder.class;
SpatialCriteriaBuilder criteriaBuilder = (SpatialCriteriaBuilder) cb.unwrap( spatialCriteriaBuilderClass );
// generate adequate query for each predicate method and model
CriteriaQuery query = getCriteriaQuery(
key,
criteriaBuilder,
model
);
List resultList = session.createQuery( query ).getResultList();
String stmt = inspector.getSqlQueries()
.get( 0 )
.toLowerCase( Locale.ROOT );
// check that generated query matches expected regex
assertTrue(
stmt.matches( regex ),
String.format( Locale.ROOT, "Statement didn't match regex:\n%s\n%s\n", stmt, regex )
);
} );
}
@Test
public void testGeolatteSpatialCriteriaIntersects() {
scope.inTransaction( (session) -> {
GeolatteSpatialCriteriaBuilder cb = session.getCriteriaBuilder()
.unwrap( GeolatteSpatialCriteriaBuilder.class );
private CriteriaQuery getCriteriaQuery(
String key,
SpatialCriteriaBuilder criteriaBuilder, Model model) {
CriteriaQuery query = criteriaBuilder.createQuery( model.entityClass );
Root root = query.from( model.entityClass );
Method method = predicateMethod( key );
finalizeQuery( criteriaBuilder, model, query, root, method );
return query;
}
CriteriaQuery<GeomEntity> cr = cb.createQuery( GeomEntity.class );
Root<GeomEntity> root = cr.from( GeomEntity.class );
cr.select( root ).where( cb.intersects(
private void finalizeQuery(
SpatialCriteriaBuilder criteriaBuilder,
Model model,
CriteriaQuery query,
Root root,
Method method) {
try {
query.select( root ).where( (Expression<Boolean>) method.invoke(
criteriaBuilder,
root.get( "geom" ),
filterGeometry
model.from.apply( filterGeometry )
) );
}
catch (IllegalAccessException | InvocationTargetException e) {
throw new JUnitException( "Failure to invoke Geometry Predicate", e );
}
}
Query<GeomEntity> query = session.createQuery( cr );
List<GeomEntity> results = query.getResultList();
assertFalse( results.isEmpty() );
} );
private Method predicateMethod(String key) {
return HSReflectionUtil.getStaticMethod(
SpatialCriteriaBuilder.class,
key,
Expression.class,
Object.class
);
}
private String displayName(Args args) {
return String.format( "Predicate %s on %s", args.method, args.model.entityClass.getSimpleName() );
}
static class Args {
final String method;
final String regex;
final Model model;
public Args(String method, String regex, Model model) {
this.method = method;
this.regex = regex;
this.model = model;
}
}
}