I'm running Neo4j 2.0.1. together with the spatial plugin for 2.0.1. together with the JDBC driver for 2.0.1. I created a simple point layer and an index for doing a spacial query. If I type in the following query in the browser, the respective nodes are returned:
START n=node:geom('withinDistance:[15.0,60.0, 200.0]') RETURN n
I wrote a method in my servlet to send this query:
//connect to database
try {
if(connection == null || connection.isClosed())
{
Class.forName("org.neo4j.jdbc.Driver"); // load jdbc driver
connection = DriverManager.getConnection("jdbc:neo4j://localhost:7474");
}
} catch (SQLException e) {
System.out.println("could not connect do DB: <br>" + e.getCause()
+ "<br>" + e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("Could not load JDBC DRIVER");
e.printStackTrace();
}
Then, I'm trying to send a request to the server:
@Path("findRange")
@GET
@Produces(MediaType.TEXT_HTML)
public String findRange(@QueryParam("lat") double lat,
@QueryParam("lon") double lon,
@QueryParam("d") double distance)
{
connectToDbIfNecessary();
try(PreparedStatement p = connection.prepareStatement(FIND_WITHIN_RANGE))
{
p.setObject(1, lat);
p.setObject(2, lon);
p.setObject(3, distance);
ResultSet rs = p.executeQuery();
return getServerResponse(rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "failure during geospatial query:\n"+e.getErrorCode()+"<br>\n"+e.getMessage()+"<br>"+e.getCause();
}
}
The prepared statement I'm sending is:
private static final String FIND_WITHIN_RANGE = "START n=node:geom('withinDistance:[{1},{2}, {3}]') RETURN n";
When I execute this on my Tomcat 7.0.53, I get the following exception:
failure during geospatial query: 0 Error executing query START n=node:geom('withinDistance:[{1},{2}, {3}]') RETURN n with params {3=1.0E8, 2=60.5, 1=14.9} java.lang.RuntimeException: Error executing cypher statement(s) [{code=Neo.DatabaseError.Statement.ExecutionFailure, message=null, stackTrace=java.lang.NullPointerException at org.neo4j.gis.spatial.indexprovider.LayerNodeIndex.query(LayerNodeIndex.java:249) at org.neo4j.gis.spatial.indexprovider.LayerNodeIndex.query(LayerNodeIndex.java:293) at org.neo4j.cypher.internal.spi.v2_0.TransactionBoundExecutionContext$NodeOperations.indexQuery(TransactionBoundExecutionContext.scala:166) at org.neo4j.cypher.internal.compiler.v2_0.spi.DelegatingOperations.indexQuery(DelegatingQueryContext.scala:113) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations.org$neo4j$cypher$internal$compiler$v2_0$spi$ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$super$indexQuery(ExceptionTranslatingQueryContext.scala:142) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$anonfun$indexQuery$1.apply(ExceptionTranslatingQueryContext.scala:142) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$anonfun$indexQuery$1.apply(ExceptionTranslatingQueryContext.scala:142) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext.org$neo4j$cypher$internal$compiler$v2_0$spi$ExceptionTranslatingQueryContext$$translateException(ExceptionTranslatingQueryContext.scala:149) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations.indexQuery(ExceptionTranslatingQueryContext.scala:142) at org.neo4j.cypher.internal.compiler.v2_0.spi.DelegatingOperations.indexQuery(DelegatingQueryContext.scala:113) at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anonfun$2$$anonfun$applyOrElse$2.apply(EntityProducerFactory.scala:66) at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anonfun$2$$anonfun$applyOrElse$2.apply(EntityProducerFactory.scala:64) at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anon$1.apply(EntityProducerFactory.scala:35) at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anon$1.apply(EntityProducerFactory.scala:34) at org.neo4j.cypher.internal.compiler.v2_0.pipes.StartPipe$$anonfun$internalCreateResults$1.apply(StartPipe.scala:34) at org.neo4j.cypher.internal.compiler.v2_0.pipes.StartPipe$$anonfun$internalCreateResults$1.apply(StartPipe.scala:33) at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply$mcZ$sp(ClosingIterator.scala:38) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:37) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:37) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.failIfThrows(ClosingIterator.scala:91) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.hasNext(ClosingIterator.scala:37) at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult.hasNext(PipeExecutionResult.scala:166) at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327) at scala.collection.convert.Wrappers$IteratorWrapper.hasNext(Wrappers.scala:29) at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult$$anon$1.hasNext(PipeExecutionResult.scala:74) at org.neo4j.server.rest.transactional.ExecutionResultSerializer.writeRows(ExecutionResultSerializer.java:291) at org.neo4j.server.rest.transactional.ExecutionResultSerializer.statementResult(ExecutionResultSerializer.java:103) at org.neo4j.server.rest.transactional.TransactionHandle.executeStatements(TransactionHandle.java:251) at org.neo4j.server.rest.transactional.TransactionHandle.commit(TransactionHandle.java:189) at org.neo4j.server.rest.transactional.TransactionHandle.commit(TransactionHandle.java:109) at org.neo4j.server.rest.web.TransactionalService$2.write(TransactionalService.java:198) at com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:71) at com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:57) at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699) at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:698) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1506) at org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1477) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:211) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1096) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:432) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:175) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1030) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136) at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.Server.handle(Server.java:445) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:268) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:229) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:601) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:532) at java.lang.Thread.run(Thread.java:722) }]
When I'm executing the query by sending a http request manually to the URL specified in the docs, I don't get an exception. I have no idea why this exception occurs. Could anyone point me in the right direction?
EDIT: It seems like index queries cannot be parameterized. However, if I do it as suggested by Stefan Armbruster, a new exception occurs (maybe this is a further problem in the 0.12 spatial implementation).
failure during geospatial query: 0 Error executing query START n=node:geom({1}) RETURN n with params {1='withinDistance:[14.9,60.5,1.0E8]'} java.lang.RuntimeException: Error executing cypher statement(s) [{code=Neo.DatabaseError.Statement.ExecutionFailure, message=only within, withinDistance and bbox are implemented., stackTrace=java.lang.UnsupportedOperationException: only within, withinDistance and bbox are implemented. at org.neo4j.gis.spatial.indexprovider.LayerNodeIndex.query(LayerNodeIndex.java:281) at org.neo4j.gis.spatial.indexprovider.LayerNodeIndex.query(LayerNodeIndex.java:293) at org.neo4j.cypher.internal.spi.v2_0.TransactionBoundExecutionContext$NodeOperations.indexQuery(TransactionBoundExecutionContext.scala:166) at org.neo4j.cypher.internal.compiler.v2_0.spi.DelegatingOperations.indexQuery(DelegatingQueryContext.scala:113) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations.org$neo4j$cypher$internal$compiler$v2_0$spi$ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$super$indexQuery(ExceptionTranslatingQueryContext.scala:142) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$anonfun$indexQuery$1.apply(ExceptionTranslatingQueryContext.scala:142) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations$$anonfun$indexQuery$1.apply(ExceptionTranslatingQueryContext.scala:142) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext.org$neo4j$cypher$internal$compiler$v2_0$spi$ExceptionTranslatingQueryContext$$translateException(ExceptionTranslatingQueryContext.scala:149) at org.neo4j.cypher.internal.compiler.v2_0.spi.ExceptionTranslatingQueryContext$ExceptionTranslatingOperations.indexQuery(ExceptionTranslatingQueryContext.scala:142) at org.neo4j.cypher.internal.compiler.v2_0.spi.DelegatingOperations.indexQuery(DelegatingQueryContext.scala:113) at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anonfun$2$$anonfun$applyOrElse$2.apply(EntityProducerFactory.scala:66) at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anonfun$2$$anonfun$applyOrElse$2.apply(EntityProducerFactory.scala:64) at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anon$1.apply(EntityProducerFactory.scala:35) at org.neo4j.cypher.internal.compiler.v2_0.executionplan.builders.EntityProducerFactory$$anon$1.apply(EntityProducerFactory.scala:34) at org.neo4j.cypher.internal.compiler.v2_0.pipes.StartPipe$$anonfun$internalCreateResults$1.apply(StartPipe.scala:34) at org.neo4j.cypher.internal.compiler.v2_0.pipes.StartPipe$$anonfun$internalCreateResults$1.apply(StartPipe.scala:33) at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply$mcZ$sp(ClosingIterator.scala:38) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:37) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:37) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.failIfThrows(ClosingIterator.scala:91) at org.neo4j.cypher.internal.compiler.v2_0.ClosingIterator.hasNext(ClosingIterator.scala:37) at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult.hasNext(PipeExecutionResult.scala:166) at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327) at scala.collection.convert.Wrappers$IteratorWrapper.hasNext(Wrappers.scala:29) at org.neo4j.cypher.internal.compiler.v2_0.PipeExecutionResult$$anon$1.hasNext(PipeExecutionResult.scala:74) at org.neo4j.server.rest.transactional.ExecutionResultSerializer.writeRows(ExecutionResultSerializer.java:291) at org.neo4j.server.rest.transactional.ExecutionResultSerializer.statementResult(ExecutionResultSerializer.java:103) at org.neo4j.server.rest.transactional.TransactionHandle.executeStatements(TransactionHandle.java:251) at org.neo4j.server.rest.transactional.TransactionHandle.commit(TransactionHandle.java:189) at org.neo4j.server.rest.transactional.TransactionHandle.commit(TransactionHandle.java:109) at org.neo4j.server.rest.web.TransactionalService$2.write(TransactionalService.java:198) at com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:71) at com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:57) at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699) at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:698) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1506) at org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1477) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:211) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1096) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:432) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:175) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1030) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136) at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.Server.handle(Server.java:445) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:268) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:229) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:601) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:532) at java.lang.Thread.run(Thread.java:722) }]
This issue seems similar to this one here from the mid of 2013.
As pointed out by Stefan Armbruster index queries don't seem to be parameterizable. Even with one parameter the query cannot be executed. So there are 2 options
1)old school Send a HTTP POST request to the url specified in the spatial docs
2)Create the String that is sent to the transactional endpoint manually:
String pay = "START n=node:geom('withinDistance:["+lat+","+lon+","+distance+"]') RETURN n";
Send the query to the endpoint without doing anything or replacing placeholders. The endpoint will then accept the query.