hibernate PostGIS几何体保存:“遇到无效的字节序标志值,”

ncecgwcz  于 2022-12-29  发布在  其他
关注(0)|答案(7)|浏览(570)

我有一个Spring Roo + Hibernate项目,它从客户端应用程序获取JTS熟知文本(WKT)字符串输入,将其转换为JTS Geometry对象,然后尝试将其写入PostGIS数据库。我在使用the JDBC connection and types时遇到了一些问题,但这些问题似乎已经通过以下方法得到了解决:

@Column(columnDefinition = "Geometry", nullable = true) 
private Geometry centerPoint;

转换过程如下:

Geometry geom = new WKTReader(new GeometryFactory(new PrecisionModel(), 4326)).read(source);

但是现在当Hibernate尝试将我的Geometry对象写入数据库时,我得到了一个错误:

2012-08-31 21:44:14,096 [tomcat-http--18] ERROR org.hibernate.util.JDBCExceptionReporter - Batch entry 0 insert into land_use (center_point, version, id) values ('<stream of 1152 bytes>', '0', '1') was aborted.  Call getNextException to see the cause.
2012-08-31 21:44:14,096 [tomcat-http--18] ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: Invalid endian flag value encountered.

很明显,这个错误与二进制表示有关,它可能是作为带有一些endianness的众所周知的二进制(WKB)生成的,但是由于Hibernate隐藏了所有的持久性,我无法真正判断事情的发展方向。
我已经和几何学的东西斗争了好几天了,关于这些错误的信息非常少,所以有人有什么好主意吗?我可以在某个地方指定字节序(Hibernate或PostGIS),或者以不同的格式存储(WKT)吗?

**EDIT:**我还应该提一下,我使用的是最新的所有软件,它们通常看起来是兼容的:

  • Spring3.1.1,车顶1.2.1
  • 休眠3.6.9
  • hibernate -空间4.0-M1
  • 联合测试系统1.12
  • PostgreSQL 9.1语言
  • postgis-jdbc 1.5.3(不是最新版本,而是recommended for hibernate-spatial,从源代码编译而来)
  • postgis-jdbc 2.0.1(刚刚尝试了这个,以匹配PostgreSQL安装的版本,同样的问题)

Hibernate Spatial 4 tutorial建议我将属性注解为:

@Type(type="org.hibernate.spatial.GeometryType")
private Geometry centerPoint;

...但是当我这样做的时候,我得到了this other error,它是当前注解解析的。

i86rm4rw

i86rm4rw1#

我通过在'application.properties'中添加以下行来解决这个问题:

spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect
aiqt4smr

aiqt4smr2#

解决办法似乎如下:
@Column,将字段Map到所需的带有JPA注解的列
@Type指定使用方言的HibernateMap。

@Column(columnDefinition = "Geometry", nullable = true) 
@Type(type = "org.hibernate.spatial.GeometryType")
public Point centerPoint;

您可以在hibernate.cfg.xml文件中添加Hibernate属性,以查看db请求,并尝试使用基于文本的编辑器(如带有“UTF-8”/“ANSI”/“other charsets”的Notepad++)捕获字符串编码的问题

<!--hibernate.cfg.xml -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>

要添加hib属性,您将有一个hibernate.cfg.xml文件,其中包含以下内容。不要复制/粘贴它,因为它是面向MySQL的。只需查看我将之前调用的属性插入的位置。

<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE hibernate-configuration PUBLIC
 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 <hibernate-configuration>
      <session-factory>
           <property name="hibernate.bytecode.use_reflection_optimizer">true</property>
           <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
           <property name="hibernate.connection.password">db-password</property>
           <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db-name</property>
           <property name="hibernate.connection.username">db-username</property>
           <property name="hibernate.default_entity_mode">pojo</property>
           <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
           <property name="hibernate.format_sql">true</property>
           <property name="hibernate.search.autoregister_listeners">false</property>
           **<property name="hibernate.show_sql">true</property>**
           <property name="hibernate.use_sql_comments">false</property>

           <mapping ressource="...." />
           <!-- other hbm.xml mappings below... -->

      </session-factory>
 </hibernate-configuration>

记录所有sql的另一种方法是在www.example.com文件中添加特定于包的属性log4j.properties:

log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE

祝你好运!

a64a0gku

a64a0gku3#

pilladooo的解决方案适用于 Boot 2.0.3、hib/spatial 5.2.17.Final和Postgres 9.5。
在我的例子中,实体中的列被定义为@Column(name =“geometry”)私有的Geometry几何;
在数据库中为类型“geometry”(以避免bytea类型由hib自动生成)
首先,我通过添加columnDefinition =“geometry”解决了“遇到无效的字节序标志值”的问题,但在此之后,Hibernate将通过“Schema-validation:在表[my_shema.my_geometry_table]的列[geometry]中遇到错误的列类型;找到[geometry(类型#OTHER)],但应为[bytea(类型#VARBINARY)]
在添加了spring.jpa.properties. hib.dialect= org.hib. spatial.dialect.postgis. postgisDialect之后,它终于工作了,列定义现在也是多余的

0lvr5msh

0lvr5msh4#

另请参阅,http://trac.osgeo.org/postgis/ticket/1830在Postgresql 9xx和Postgis 2xx发布时出现了一个问题,在使用postgres实用程序pgsql2shp时导致了相同的“an invalid endian flag”错误。可以通过删除旧版本的库www.example.com来修复libpq.so,因为这是由于Postgres更改了bytea的默认行为。

dwthyt8l

dwthyt8l5#

我得到了它的工作与以下配置。我使用的是Spring Boot 2.5.1,PostGIS和休眠空间5.4.32.Final。几个关键点:
1.我使用的Point类是org. locationtech. jts. geom. Point
1.你不需要特别的注解,这是我的实体类。
实体:

@Enity public class Vehicle {

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

    private String name;    
    
    private Point location;
}

Also in the application.properties, I use

spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect

然后在服务类中,我可以通过调用将对象保存到数据库中,如下所示。

public Vehicle createVehicle(String name, Double longitude, Double latitude) {
    GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326);
        var point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
    
        var vehicle = new Vehicle(name, point);      
        return vehicleRepository.save(vehicle);
}
vjhs03f7

vjhs03f76#

经过一些斗争与给定的问题,这里是帮助我解决它的步骤。首先,我应该提到我使用WildFly 17服务器,PostgreSQL 12和PostGIS 3.0.0。现在的步骤,我认为在这个问题是重要的:
META-INF中创建jboss-deployment-structure.xml文件(如果没有),并排除WildFly附带的休眠

<jboss-deployment-structure>
    <deployment>
        <exclusions>
            <module name="org.hibernate" />
        </exclusions>
    </deployment>
</jboss-deployment-structure>

pom.xml中添加依赖项

<dependency>
    <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
    <version>5.4.12.Final</version>
</dependency>

以及

<dependency>
    <groupId>org.hibernate</groupId>
        <artifactId>hibernate-spatial</artifactId>
    <version>5.4.12.Final</version>
</dependency>

确保hibcore和hibspatial有相同的版本(使用你喜欢的任何版本)。
您的persistence.xml应该具有属性

<property name="hibernate.dialect" value="org.hibernate.spatial.dialect.postgis.PostgisDialect"/>

最后,我认为这不是很重要,但我在Java中使用了org.locationtech.jts来表示几何图形。
我希望我没有忽略任何重要的东西,这些都是必需的步骤。有可能是其他的东西,但许多小时已经过去了,在尝试不同的解决方案,有可能是我忘记了包括一些依赖关系/属性。答案是基于个人经验,因此请随时评论,以证明我错了或扩大答案。无论如何,我希望有人会发现这个答案有用。

b4qexyjb

b4qexyjb7#

对于那些还在纠结这个问题的人,我已经纠结了好几天了,结果发现我的问题是,我用错了包。com.vividsolutions中的几何图形已经被移到了org.locationtech中。所以你应该使用org.locationtech。Maven说

相关问题