PostGIS Geometry save:"遇到无效的endian标志值."

orl*_*ade 8 geometry spring hibernate jts endianness

我有一个Spring Roo + Hibernate项目,该项目从客户端应用程序获取JTS着名文本(WKT)字符串输入,将其转换为JTS Geometry对象,然后尝试将其写入PostGIS数据库.我在JDBC连接和类型方面遇到了一些问题,但这些问题似乎已经解决了:

@Column(columnDefinition = "Geometry", nullable = true) 
private Geometry centerPoint;
Run Code Online (Sandbox Code Playgroud)

转换确实:

Geometry geom = new WKTReader(new GeometryFactory(new PrecisionModel(), 4326)).read(source);
Run Code Online (Sandbox Code Playgroud)

但是现在当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.
Run Code Online (Sandbox Code Playgroud)

很明显,该错误与二进制表示有关,二进制表示可能是作为具有某种字节顺序的众所周知的二进制(WKB)生成的.然而,随着Hibernate将所有持久性隐藏起来,我无法确定事情的发展方向.

几天来我一直在与这种几何学作斗争,关于这些错误的信息很少,所以有没有人有任何好主意?我可以在某处指定字节顺序(Hibernate或PostGIS),还是以不同的格式(WKT)存储?

编辑:我还应该提到我正在使用最新的一切,通常似乎是兼容的:

  • Spring 3.1.1,Roo 1.2.1
  • 休眠3.6.9
  • hibernate-spatial 4.0-M1
  • jts 1.12
  • PostgreSQL 9.1
  • postgis-jdbc 1.5.3(不是最新的,但建议用于hibernate-spatial,从源代码编译)
  • postgis-jdbc 2.0.1(现在试过这个以匹配PostgreSQL安装的版本,同样的问题)

Hibernate的空间4教程建议我做的属性注解为:

@Type(type="org.hibernate.spatial.GeometryType")
private Geometry centerPoint;
Run Code Online (Sandbox Code Playgroud)

...但是当我这样做时,我得到另一个错误,当前注释解决了.

Thi*_*ryB 8

解决方案似乎如下:
@Column使用JPA注释将字段映射到所需列,
@Type以使用方言指定Hibernate映射.

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

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

<!--hibernate.cfg.xml -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
Run Code Online (Sandbox Code Playgroud)

要添加hibernate属性,您将拥有一个带有以下内容的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>
Run Code Online (Sandbox Code Playgroud)

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

log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE
Run Code Online (Sandbox Code Playgroud)

祝好运!


小智 8

我将这一行添加到'application.properties'中来解决此问题:

spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect
Run Code Online (Sandbox Code Playgroud)


小智 5

对于那些仍然为这个问题苦苦挣扎的人,我已经为此苦苦挣扎了好几天,事实证明我的问题是,我使用了错误的软件包。几何图形com.vividsolutions已移至org.locationtech。所以你应该使用org.locationtech. 梅文说