본문 바로가기

오류일기

[JPA] PostgreSQL을 사용하는 환경에서 Point 타입 사용하기

프로젝트를 진행하면서 반경검색을 해야할 일이 있었습니다. 그리고 기존에 사용하고 있던 MySQL로는 부정확하며 로직을 수행하는 시간 역시 PostgreSQL에 비해 떨어졌습니다.

아래는 당시 저의 생각을 작성해 이슈로 올린 링크입니다.

https://github.com/GDSC-KNU/3rd-sc-ex1-CitySavior-Backend/issues/5

 

[FEAT] 신고조회 기능 구현 · Issue #5 · GDSC-KNU/3rd-sc-ex1-CitySavior-Backend

Description 📝 단일 신고 조회 기능 DB로 부터 단순 조회입니다. 지도에서 신고현황 조회 기능 요청 파라미터로부터 인근에 존재하는 신고 정보를 반환하는 기능입니다. DB변경 파라미터로 넘어오

github.com

 

그렇기에 PostgreSQL + PostGIS 기반으로 DB를 변경하고 반경검색 로직을 수행하고자 하였습니다.

PostgreSQL을 처음 써보는 저의 심정을 대변한는 짤입니다..


먼저 저는 제가 해야 하는 행동들을 나누어 보기로 하였습니다.

  1. GCP의 Cloud SQL 인스턴스를 Mysql에서 PostgreSQL로 변경하기
  2. Data JPA에서 Point타입을 사용하기 위한 환경설정및 코드 작성
  3. 반경 검색 로직 구현

그리고 1번의 경우는 그저 GCP의 Cloud SQL의 DB를 PostgreSQL로 수정하기만 되기에 쉽게 해결해나갔습니다만...

저는 2번이 문제가 되었습니다.

geometry Type이 존재하지 않는다고 합니다..

 

이러한 오류가 발생하는 이유에 대한 정확한 이유는 찾지 못하였지만 구글링을 한 결과 다음과 같은 결론을 내릴 수 있습니다.

자바에서는 공간 정보를 담는 Point 타입을 import org.locationtech.jts.geom 를 통해 사용할 수 있습니다. 그리고 PostgreSQL에서는 공간 정보를 geomety 타입으로 저장합니다.

그리고 정확히는 PostgreSQL에서 공간 정보를 다루는 것이 아닌 PostGIS라는 외부 확장툴이 공간 정보를 다룹니다. 그리고 이 PostGIS는 PostgeSQL을 설치할 때 기본적으로 같이 설치가 되지만 

사용하기 위해서는 PostGIS를 확장툴로써 사용한다고 PostgreSQL에게 알려주어야 합니다.

 

저는 제가 내린 결론을 기반으로 먼저 double타입으로 되어 있던 위도와 경도를 Point타입으로 수정해주었습니다.

 

바꾸기 전 위도와 경도를 double타입으로 선언한 코드입니다.

@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class Report {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "report_id")
    private Long report_id;
    private double weight;
    private double latitude;
    private double longitude;
    private String description;
    private String img_url;
    private double damage_ratio;
    private LocalDate repaired_date;
    private LocalDate report_date;
    @OneToMany(mappedBy = "report")
    private List<ReportComment> comments;
}

 

아래는  import org.locationtech.jts.geom의Point타입으로 변경한 코드입니다.

...
import org.locationtech.jts.geom.*;
...

@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class Report {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "report_id")
    private Long report_id;
    private double weight;
    @Column(columnDefinition = "geometry(Point, 4326)")
    private Point location;
    private String description;
    private String img_url;
    private double damage_ratio;
    private LocalDate repaired_date;
    private LocalDate report_date;
    @OneToMany(mappedBy = "report")
    private List<ReportComment> comments;
}

 

DB에 존재하는 쿼리에 대한 조회를 하였을때 나오는 결과창입니다.

 

Ref

https://pamyferret.tistory.com/29