We're updating the issue view to help you get more done. 

Using DistanceSortField does not verify the field parameter passed to the constructor

Description

It is possible to use DistanceSortField on non existent or non spatial fields without warning or error. From SpatialIndexingTest:

SpatialIndexingTest.java

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 @Test public void testNonGeoDistanceSort() throws Exception { NonGeoPOI poi = new NonGeoPOI( 1, "Distance to 24,32 : 0", 24.0d, null, "" ); NonGeoPOI poi2 = new NonGeoPOI( 2, "Distance to 24,32 : 24.45", 24.2d, 31.9d, "" ); NonGeoPOI poi3 = new NonGeoPOI( 3, "Distance to 24,32 : 10.16", 24.0d, 31.9d, "" ); NonGeoPOI poi4 = new NonGeoPOI( 4, "Distance to 24,32 : 15.06", 23.9d, 32.1d, "" ); NonGeoPOI poi5 = new NonGeoPOI( 5, "Distance to 24,32 : 11.12", 23.9d, 32.0d, "" ); NonGeoPOI poi6 = new NonGeoPOI( 6, "Distance to 24,32 : 22.24", 24.2d, 32.0d, "" ); FullTextSession fullTextSession = Search.getFullTextSession( openSession() ); Transaction tx = fullTextSession.beginTransaction(); fullTextSession.save( poi ); fullTextSession.save( poi2 ); fullTextSession.save( poi3 ); fullTextSession.save( poi4 ); fullTextSession.save( poi5 ); fullTextSession.save( poi6 ); tx.commit(); tx = fullTextSession.beginTransaction(); double centerLatitude = 24.0d; double centerLongitude = 32.0d; final QueryBuilder builder = fullTextSession.getSearchFactory() .buildQueryBuilder().forEntity( NonGeoPOI.class ).get(); org.apache.lucene.search.Query luceneQuery = builder.all().createQuery(); FullTextQuery hibQuery = fullTextSession.createFullTextQuery( luceneQuery, NonGeoPOI.class ); Sort distanceSort = new Sort( new DistanceSortField( centerLatitude, centerLongitude, "location" )); hibQuery.setSort( distanceSort ); hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE ); hibQuery.setSpatialParameters( centerLatitude, centerLongitude, "location" ); List<Object[]> results = hibQuery.list(); Double previousDistance = (Double) results.get( 0 )[1]; for ( Object[] projectionEntry : results ) { Double currentDistance = (Double) projectionEntry[1]; assertTrue( previousDistance + " should be <= " + currentDistance, previousDistance <= currentDistance ); previousDistance = currentDistance; } tx.commit(); }

where NonGeoPOI looks like this:

NonGeoPOI.java

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 @Entity @Indexed public class NonGeoPOI { @Id Integer id; @Field(store = Store.YES) String name; @Field(store = Store.YES, index = Index.YES) String type; @Field(store = Store.YES, index = Index.YES) @NumericField Double latitude; @Field(store = Store.YES, index = Index.YES) @NumericField Double longitude; public NonGeoPOI(Integer id, String name, Double latitude, Double longitude, String type) { this.id = id; this.name = name; this.latitude = latitude; this.longitude = longitude; this.type = type; } public NonGeoPOI() { } public Integer getId() { return id; } public String getName() { return name; } public double getLatitude() { return latitude; } public double getLongitude() { return longitude; } public String getType() { return type; } }

The test refers to a field location which does not even exist. The code does neither fail or log a warning. The projected distance value is constant for all indexed points.

One could try to verify whether the field exists using the meta data, but this requires that the targeted entity is known. What would one do, if all entities are targeted? Does this even make sense?

Environment

None

Status

Assignee

Davide D'Alto

Reporter

Hardy Ferentschik

Labels

Suitable for new contributors

None

Feedback Requested

None

Components

Fix versions

Affects versions

5.0.0.Beta1

Priority

Major