如何在 spring data-jpa + mysql 8 中插入地理点列?

Jer*_*rry 5 spring-data-jpa hibernate-spatial

我的环境

  • mysql 8.0.25
  • 休眠核心:5.4.32
  • 休眠空间:5.4.32
  • spring-boot2.5.4
  • 爪哇8

我做了什么

应用程序.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/database?serverTimezone=UTC&characterEncoding=UTF-8
    username: root
    password: password
  jpa:
    hibernate.ddl-auto: create
    generate-ddl: true
    database: mysql
    properties:
      hibernate.dialect: org.hibernate.spatial.dialect.mysql.MySQL56SpatialDialect

logging:
  level:
   org:
    hibernate:
      SQL: debug
      type: trace

Run Code Online (Sandbox Code Playgroud)

实体类

import com.example.mypackage.domain.BaseTimeEntity;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.geo.Point;

import javax.persistence.*;

@Getter
@NoArgsConstructor
@Entity
public class Party extends BaseTimeEntity { // BaseTimeEntity adds modifiedAt, createdAt columns

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(columnDefinition = "TEXT")
    private String title;

    @Column(columnDefinition = "POINT")
    private Point coordinate;

    @Builder
    public Party(Point coordinate, String title, String body) {
        this.coordinate = coordinate;
        this.title = title;
        this.body = body;
    }
}


Run Code Online (Sandbox Code Playgroud)

测试

@SpringBootTest
class PartyRepositoryTest {

    @Autowired
    PartyRepository partyRepository;

    @Test
    public void register_party() {
        // Given
        Double x = 127.02558;
        Double y = 37.30160;
        Point coordinate = new Point(x, y);
        partyRepository.save(
            Party.builder()
                    .coordinate(coordinate)
                    .title("test title")
                    .build()
        );

        // When
        List<Party> partyList = partyRepository.findAll();

        // Then
        Party party = partyList.get(0);
        assertEquals(x, party.getCoordinate().getX());
        assertEquals(y, party.getCoordinate().getY());
    }

Run Code Online (Sandbox Code Playgroud)

我所期望的

在“party”表中成功插入行

到底发生了什么

我收到错误。日志如下。

insert into party (created_at, modified_at, body, coordinate, title) values (?, ?, ?, ?, ?)
binding parameter [1] as [TIMESTAMP] - [2021-09-12T14:45:31.018]
binding parameter [2] as [TIMESTAMP] - [2021-09-12T14:45:31.018]
binding parameter [3] as [VARCHAR] - []
binding parameter [4] as [VARBINARY] - [Point [x=127.025580, y=37.301600]]
binding parameter [5] as [VARCHAR] - [test title]
SQL Error: 1416, SQLState: 22001
Data truncation: Cannot get geometry object from data you send to the GEOMETRY field
Run Code Online (Sandbox Code Playgroud)

问题

  • 请让我知道我做错了什么?
  • hibernate-spatial支持mysql点吗?

小智 3

您使用了错误的空间类型:org.springframework.data.geo.PointHibernate Spatial 不支持。在您的实体类中使用 或org.locationtech.jts.geom.*应该org.geolatte.geom.*没问题。