【问题标题】:Mapping to com.vividsolutions.jts.geom.Point invalid endian flag映射到 com.vividsolutions.jts.geom.Point 无效字节序标志
【发布时间】:2017-06-22 01:05:36
【问题描述】:

我正在开展一个项目,我将在其中检索用户的纬度和经度。由此,我想将它作为一个点存储到数据库中。但是,当我尝试这样做时,我遇到了以下错误:o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: Invalid endian flag value encountered.

我正在采用暴露给客户端的模型并将其映射如下:

 public static Point createPoint(double longitude, double latitude){
        GeometryFactory gf = new GeometryFactory();

        Coordinate coord = new Coordinate(longitude, latitude );
        Point point = gf.createPoint( coord );

        return point;
    }

所以我会粗略地调用这个方法来将值映射为一个点:

createPoint(user.getLocation().getLongitude(), user.getLocation().getLatitude());

然后我会将返回的值存储到数据库中。

我的 pom 文件有以下依赖:

    <dependency>
        <groupId>com.vividsolutions</groupId>
        <artifactId>jts</artifactId>
        <version>1.13</version>
   </dependency>
   <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-spatial</artifactId>
          <version>5.2.4.Final</version>
                <exclusions>
                    <exclusion>
                        <artifactId>postgresql</artifactId>
                        <groupId>postgresql</groupId>
                    </exclusion>
                </exclusions>
    </dependency>

jpa 配置:

jpa:
        database: POSTGRESQL
        open-in-view: false
        show-sql: true
        hibernate:
            ddl-auto: none
            dialect: org.hibernate.spatial.dialect.postgis.PostgisDialect
            naming:
                naming-strategy: org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy

列定义:

@Column(name="point")
private com.vividsolutions.jts.geom.Point point;

关于如何修复此错误的任何想法? 提前谢谢大家。

【问题讨论】:

  • 不确定是否理解您的正确,但不是javax.persistence.AttributeConverter 您在寻找什么?

标签: java spring hibernate postgis spatial


【解决方案1】:

您可以通过多种方式完成此操作,这完全取决于您希望数据如何存储在底层数据存储中。

正如 cmets 中所指出的,您可以使用AttributeConverter 实现将Point 坐标的xyz 组件存储在由某种魔法分隔的单列中人物:

public class PointerConverter implements AttributeConverter<Point, String> {
   @Override
   public String converToDatabaseColumn(Point point) {
     // read the x, y, z, construct a string delimited by some character and
     // return the value.  Hibernate will store this in your column.
   }

   @Override
   public Point convertToEntityAttribute(String value) {
     // split the value by the delimiter and construct a Point.
     // return the constructed Point to be set in the entity.
   }
}

这种方法的一个固有问题是它几乎不可能查询Point 坐标的各个部分。

如果您发现您需要能够查询Point 并提供构成Point 坐标的各种xyz 值,那么您将最好考虑一下:

  • 自定义UserType 实现
  • 使用@Embeddable 在持久性世界中代表您的Point

对于自定义UserType,您需要定义一个新类型,在此示例中可能称为PointType,扩展UserType,并按如下方式引用它:

@Type(type = "PointType")
@Columns({@Column(name = "X"), @Column(name="Y"), @Column(name="Z"))
private Point point;

自定义UserType 将处理将点坐标的xyz 部分映射到相应的列XYZ,反之亦然。

对于@Embeddable 解决方案,您只需创建自己的JpaPoint 类,您可以将其传入几何Point 类,以便它读取xyz 值并将它们存储在持久性模型的 3 个属性中。然后 JpaPoint 类还可以公开一个帮助方法,允许调用者从 JpaPoint 嵌入生成 Point

// ctor example
public JpaPoint(Point point) {
  this.x = point.getCoordinates().x;
  this.y = point.getCoordinates().y;
  this.z = point.getCoordinates().z;
}

// helper method
@Transient
public Point getPoint() {
  return new Point( new Coordinates( x, y, z ) );
}

【讨论】:

  • 非常感谢您的深入回复。我进一步尝试创建另一个实用程序类来使用 WKTReader & writer 从 lon/lat 转换为 com.vividsolutions.jts.geom.Point point ,但仍然没有运气。我将尝试您的最后一个想法,而是按照您的建议创建一个可嵌入点 - 这应该可以解决问题。再次感谢!
  • 拜托,你能把 JPAPoint(可嵌入)的 AttributeConverter 放到 Point(vividsolutions)吗?谢谢
猜你喜欢
  • 1970-01-01
  • 2020-05-09
  • 2013-12-03
  • 2017-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多