SQL 到 JPQL - 半正弦公式
SQL to JPQL - haversine formula
我有这个 SQL 查询,它返回地点 table 的位置,并按以公里为单位的距离排序。
该查询在 SQL 中有效,但我在将其转换为 JPQL 时遇到了一些困难。
我暂时使用静态值以使其更易于阅读。
SQL - 有效
SELECT DISTINCT *,( 6371 * acos( cos( radians(60.1733) ) * cos( radians( spot.spot_latitude ))
* cos( radians(spot.spot_longitude) - radians(24.941)) + sin(radians(60.1733))
* sin( radians(spot.spot_latitude)))) AS distance
FROM spot
WHERE spot_id = spot_id
HAVING distance < 10
ORDER BY distance
JPQL - 不起作用
SELECT DISTINCT s, ( 6371 * acos( cos( radians(60.1733) ) * cos( radians( spot.spot_latitude ))
* cos( radians(spot.spot_longitude) - radians(24.941)) + sin(radians(60.1733))
* sin( radians(spot.spot_latitude)))) AS distance
FROM spot
WHERE s.spot_id = s.spot_id
HAVING distance < 10
ORDER BY s.distance
JPQL 抛出两个异常,其根本原因是:
A MultiException has 2 exceptions. They are:
1. org.eclipse.persistence.exceptions.PersistenceUnitLoadingException:
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: ParallelWebappClassLoader
context: skatebayBackend
delegate: false
----------> Parent Classloader:
java.net.URLClassLoader@2f2c9b19
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [skatebay_pu] failed.
Internal Exception: Exception [EclipseLink-7158] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Error encountered when building the @NamedQuery [Spot.getSpotsInMyArea] from entity class [class org.eclipse.persistence.internal.jpa.metadata.queries.NamedQueryMetadata].
Internal Exception: java.lang.ClassCastException: org.eclipse.persistence.jpa.jpql.parser.NullExpression cannot be cast to org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable
2. java.lang.IllegalStateException: Unable to perform operation: create on rest.SpotApi
JPQL 适用于实体而非数据库 tables。您在这里至少有两个选择:
确保您已将实体映射到 table 并为您的查询使用正确的语法。然而,JPQL 提供的可能性比 SQL 少。
所以也许在你的情况下创建原生查询会更容易,然后你可以使用正常的 sql。
Query query = getEntityManager().createNativeQuery("select * from table...");
List<Object> string = query.getResultList();
您在 JPQL 中的 where 子句中使用了别名 s
,请改为这样做。
SELECT DISTINCT s, ( 6371 * acos( cos( radians(60.1733) ) * cos( radians( spot.spot_latitude ))
* cos( radians(spot.spot_longitude) - radians(24.941)) + sin(radians(60.1733))
* sin( radians(spot.spot_latitude)))) AS distance
FROM spot AS s
WHERE s.spot_id = s.spot_id
HAVING distance < 10
ORDER BY s.distance
我有这个 SQL 查询,它返回地点 table 的位置,并按以公里为单位的距离排序。 该查询在 SQL 中有效,但我在将其转换为 JPQL 时遇到了一些困难。 我暂时使用静态值以使其更易于阅读。
SQL - 有效
SELECT DISTINCT *,( 6371 * acos( cos( radians(60.1733) ) * cos( radians( spot.spot_latitude ))
* cos( radians(spot.spot_longitude) - radians(24.941)) + sin(radians(60.1733))
* sin( radians(spot.spot_latitude)))) AS distance
FROM spot
WHERE spot_id = spot_id
HAVING distance < 10
ORDER BY distance
JPQL - 不起作用
SELECT DISTINCT s, ( 6371 * acos( cos( radians(60.1733) ) * cos( radians( spot.spot_latitude ))
* cos( radians(spot.spot_longitude) - radians(24.941)) + sin(radians(60.1733))
* sin( radians(spot.spot_latitude)))) AS distance
FROM spot
WHERE s.spot_id = s.spot_id
HAVING distance < 10
ORDER BY s.distance
JPQL 抛出两个异常,其根本原因是:
A MultiException has 2 exceptions. They are:
1. org.eclipse.persistence.exceptions.PersistenceUnitLoadingException:
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: ParallelWebappClassLoader
context: skatebayBackend
delegate: false
----------> Parent Classloader:
java.net.URLClassLoader@2f2c9b19
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [skatebay_pu] failed.
Internal Exception: Exception [EclipseLink-7158] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Error encountered when building the @NamedQuery [Spot.getSpotsInMyArea] from entity class [class org.eclipse.persistence.internal.jpa.metadata.queries.NamedQueryMetadata].
Internal Exception: java.lang.ClassCastException: org.eclipse.persistence.jpa.jpql.parser.NullExpression cannot be cast to org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable
2. java.lang.IllegalStateException: Unable to perform operation: create on rest.SpotApi
JPQL 适用于实体而非数据库 tables。您在这里至少有两个选择:
确保您已将实体映射到 table 并为您的查询使用正确的语法。然而,JPQL 提供的可能性比 SQL 少。
所以也许在你的情况下创建原生查询会更容易,然后你可以使用正常的 sql。
Query query = getEntityManager().createNativeQuery("select * from table...");
List<Object> string = query.getResultList();
您在 JPQL 中的 where 子句中使用了别名 s
,请改为这样做。
SELECT DISTINCT s, ( 6371 * acos( cos( radians(60.1733) ) * cos( radians( spot.spot_latitude ))
* cos( radians(spot.spot_longitude) - radians(24.941)) + sin(radians(60.1733))
* sin( radians(spot.spot_latitude)))) AS distance
FROM spot AS s
WHERE s.spot_id = s.spot_id
HAVING distance < 10
ORDER BY s.distance