HHH-14982 Fix SQL Errors, add javadoc and extend spatial criteria tests
This commit is contained in:
parent
3b14107c49
commit
3abc8c940a
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue