【问题标题】:How would I use NEAR with MySQL and JPA我如何将 NEAR 与 MySQL 和 JPA 一起使用
【发布时间】:2018-10-22 18:09:15
【问题描述】:

好像不支持NEAR:

我收到此错误:

不支持的关键字 NEAR (1):[IsNear, Near]

这是我的仓库:

public interface GeoTestRepository extends JpaRepository<GeoTest, String> {
    GeoResults<GeoTest> findByLocationNear(Point p, Distance d);
}

至于MySql:

SELECT VERSION();
8.0.11

连接器的依赖是:

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.11</version>
    </dependency>

我的实体是:

import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Arrays;
@Entity
public class GeoTest {

    @Id
    private String id; // SET/GET
    private GeoJsonPoint location; // SET/GET
}

以下是我得到的确切异常。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'geoTestController': Unsatisfied dependency expressed through field 'geoTestRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'geoTestRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.geo.GeoResults com.example.demo.repository.GeoTestRepository.findByLocationNear(org.springframework.data.geo.Point,org.springframework.data.geo.Distance)! Unsupported keyword NEAR (1): [IsNear, Near]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:587) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:373) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'geoTestRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.geo.GeoResults com.example.demo.repository.GeoTestRepository.findByLocationNear(org.springframework.data.geo.Point,org.springframework.data.geo.Distance)! Unsupported keyword NEAR (1): [IsNear, Near]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    ... 42 common frames omitted
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.geo.GeoResults com.example.demo.repository.GeoTestRepository.findByLocationNear(org.springframework.data.geo.Point,org.springframework.data.geo.Distance)! Unsupported keyword NEAR (1): [IsNear, Near]
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:82) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
    ... 52 common frames omitted
Caused by: java.lang.IllegalArgumentException: Unsupported keyword NEAR (1): [IsNear, Near]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:318) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:206) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
    ... 78 common frames omitted

2018-05-21 15:47:36.276 ERROR 9512 --- [           main] o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@4218d6a3] to prepare test instance [com.example.demo.test.GeoTestTest@52ca2652]

【问题讨论】:

  • 你检查过this answer吗?此外,如果该解决方案不适合您,您可以考虑提供有关您的设置的更多信息:您拥有什么 Hibernate/SpringBoot 版本?您使用的是什么 MySQL 版本?抛出异常时您的方法调用如何?确切的堆栈是什么?另外,您可以参考帮助页面“How to create a Minimal, Complete, and Verifiable example”。
  • SQL 日志转储和确切异常有助于回答
  • 我不确定如何转储 SQL 日志
  • @Noman 你最后做了什么,我也遇到了同样的问题,为不同的方法做了几次尝试,没有任何效果。
  • @PankajArora 我决定使用 mongoDB。

标签: mysql spring-boot spring-data-jpa mysql-8.0


【解决方案1】:

请试试这个:

实体

@Entity
public class GeoTest {

    @Id
    private String id; // SET/GET
    @GeoIndexed 
    private Point location; // SET/GET
}

存储库

public interface GeoTestRepository extends Repository<GeoTest, String> {
    List<GeoTest> findByLocationNear(Point p, Distance d);
}

【讨论】:

    【解决方案2】:

    Spring Data JPA 基于 JPA。派生查询基于 JPA Criteria API 创建查询。 near 似乎是 MySql 对 SQL 的扩展。因此,您的分析是正确的:派生查询不支持 near。

    改用@Query 注释和native=true

    【讨论】:

      【解决方案3】:

      这是基于 MySql Query + Spring Data JPA + Rest Services。您需要在 URL 中传递 lat/lang 坐标。

      @RestController
      @RequestMapping("api/admin/")
      public class AdminController {
      
          @Autowired
          private UserRepository userRepository;
      
      
      
          @GetMapping("nearbyusers/{latitude}/{longitude}")
          public List<User> getNearbyUsers(@PathVariable double latitude,@PathVariable double longitude)  {
              List<User> nearbyUsers=  this.userRepository.findAllNearByUsers(latitude,longitude);
      
      
              return nearbyUsers;
      
          }
      
      
      }
      
      
      @Repository
      public interface UserRepository extends JpaRepository<User, Long> {
      
           @Query(value ="SELECT *, ( 6371 * acos( cos( radians(?1) ) * cos( radians(  latitude ) ) * cos( radians( longitude ) - radians(?2) ) + sin(     radians(?1) ) * sin( radians( latitude ) ) ) ) AS distance FROM user WHERE roles='USER' HAVING distance < 20 ORDER BY distance LIMIT 0 , 20",nativeQuery = true)
           List<User> findAllNearByUsers(double lat,  double longi);
      
      
           User findByUsername(String username);
      
      
      }
      

      【讨论】:

        猜你喜欢
        • 2015-03-14
        • 2020-11-19
        • 1970-01-01
        • 2013-03-05
        • 2015-03-01
        • 1970-01-01
        • 2015-03-18
        • 2015-01-12
        • 2017-10-11
        相关资源
        最近更新 更多