views:

282

answers:

2

I'm have entities with latitude and longitude and I would like to select those nearest to a given point.

I found this example that looks like it would work

SELECT *,
    SQRT(POW((69.1 * (locations.latitude - 27.950898)) , 2 ) +
    POW((53 * (locations.longitude - -82.461517)), 2)) AS distance
FROM locations
ORDER BY distance ASC
LIMIT 5

But I would prefer to do it with JPQL since I have a bunch of other joins etc that feels easier to do in JPQL instead of native query.

When I try something like this the JPA is complaining about the SQRT token.

SELECT DISTINCT p, SQRT(....) AS distance, FROM Place p .... ORDER BY distance ASC

Anyone has knows how to write a query like this, or maybe another better approach?

Thanks! /Oskar

A: 

The JPQL language reference says that:

functions_returning_numerics ::= ABS(simple_arithmetic_expression) | SQRT(simple_arithmetic_expression) | MOD(simple_arithmetic_expression, simple_arithmetic_expression) | SIZE(collection_valued_path_expression)

So, you don't have POW.

You can safely use a native query.

The approach I'd prefer, though, is to make the query without the calculations and then make the calculation on the result in your code. It shouldn't be a big performance hazard.

Bozho
Since Oskar only needs a power of 2 the query should be writable without POW, although it will be wordy one. Strange that it complains about SQRT. I will experiment with it.
rayd09
Come to think of it you don't even need the SQRT to do the query that you want. You select for and order by the square of the distance and not take the square root until you have your small set of results. The ordering will be the same whether you use the square of the distance or the distance itself.
rayd09
Good idea that the POW can be expanded and that SQRT doesn't matter in the comparison. The problem is that I can't get any calculations to work if they are put before the FROM. I'm not sure how JPQL works with this and if its possible at all. Worst case I guess I have to fall back to native SQL.
Oskar
I tried to use NEW and create my entity with the lat and long as parameter and calculate the distance as a transient value, but it refused to accept the constructor variables.I think native SQL is the only way to go.
Oskar
A: 

As far as I can tell from researching this and may trial and errors JPQL is simply not equipped to handle this scenario. I had to rewrite my queries as native.

Oskar