Сохранение геометрии PostGIS: обнаружено недопустимое значение флага порядка байтов.

У меня есть проект Spring Roo + Hibernate, который принимает ввод строки известного текста JTS (WKT) из клиентского приложения, преобразует его в объект JTS Geometry, а затем пытается записать его в базу данных PostGIS. У меня были проблемы с соединением JDBC и типами, но, похоже, они были решены с помощью:

@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.

Кажется очевидным, что ошибка связана с двоичным представлением, которое предположительно создается как хорошо известный двоичный файл (WKB) с некоторым порядок байтов. Однако с Hibernate, скрывающим всю настойчивость, я не могу точно сказать, в каком направлении идут дела.

Я боролся с этой геометрией несколько дней, и информации об этой ошибке очень мало, так что у кого-нибудь есть какие-нибудь блестящие идеи? Могу ли я где-нибудь указать порядок байтов (Hibernate или PostGIS) или, возможно, сохранить в другом формате (WKT)?

РЕДАКТИРОВАТЬ: Я также должен упомянуть, что я использую все самое новое, что в целом кажется совместимым:

  • Spring 3.1.1, Roo 1.2.1
  • спящий режим 3.6.9
  • спящий пространственный 4.0-M1
  • jts 1.12
  • PostgreSQL 9.1
  • postgis-jdbc 1.5.3 (не последняя, ​​но рекомендуется для hibernate-space, скомпилировано из исходников) )
  • postgis-jdbc 2.0.1 (просто попробовал это сейчас, чтобы соответствовать версии, установленной с PostgreSQL, та же проблема)

В руководстве по Hibernate Spatial 4 предлагается использовать аннотацию свойств как:

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

... но когда я это сделаю, я получаю эту другую ошибку, которую разрешает текущая аннотация.


person orlade    schedule 31.08.2012    source источник
comment
Еще раз здравствуйте, я слежу за вашими проблемами с OpenGIS :) Вы пытались сделать двойные методы @Type(type="org.hibernate.spatial.GeometryType") аннотации плюс аннотации JPA @Column(columnDefinition = "Geometry", nullable = true), связанные с одним и тем же полем.   -  person BendaThierry.com    schedule 31.08.2012
comment
У других библиотек есть проблемы, подобные этой geodb issue n ° 5. Я предлагаю вам попробовать набор тестов postgis, чтобы увидеть, не сталкиваетесь ли вы с той же проблемой. Это похоже на проблему с кодировкой endian символов, хорошо, но иногда все не так, как кажется на первый взгляд. Вы пытались получить больше информации с помощью метода getNextException() или вторая строка ваших журналов - это все, что вы можете получить об этом?   -  person BendaThierry.com    schedule 31.08.2012
comment
Я нашел следующее руководство по java hibernate postgis которые предлагают делать то, что я сказал. Это на французском, хорошо, но я могу помочь, если вам понадобится переводчик (я французский, лол). В предлагаемом руководстве кратко объясняется роль каждой аннотации, которую я использовал в своем первом комментарии. Похоже, вам нужно установить их, как я предлагал.   -  person BendaThierry.com    schedule 31.08.2012


Ответы (5)


Решение выглядит следующим образом:
@Column для сопоставления поля с нужным столбцом с аннотациями JPA
@Type для указания сопоставления Hibernate с диалектом.

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

Вы можете добавить свойство Hibernate в файл hibernate.cfg.xml, чтобы увидеть запрос базы данных и попытаться отловить строковую проблему с помощью текстового редактора, такого как Notepad ++, с «UTF-8» / «ANSI» / «другие кодировки»

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

Чтобы добавить свойства гибернации, у вас будет файл 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 - добавить специфические свойства пакета в файл log4j.properties:

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

Удачи!

person BendaThierry.com    schedule 31.08.2012
comment
Это определенно решает проблему с порядком байтов, так что спасибо. Однако, как и ожидалось, у меня теперь другая внутренняя ошибка: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction. Трассировка стека бесполезна, а заставить работать теги конфигурации гибернации труднее, чем ожидалось. Для вас это очевидно, или для этого нужно задать новый вопрос? - person orlade; 01.09.2012
comment
Привет, может быть, ищу какие-нибудь @Transactional вещи. У меня сегодня мало времени (шахматное мероприятие). Может быть, я смогу тебе помочь завтра. Я добавлю полную конфигурацию гибернации, чтобы вы могли на нее взглянуть. Удачи! - person BendaThierry.com; 01.09.2012
comment
Хм. Возможно, ваша модель базы данных не допускает нулевых значений для любого поля, связанного с объектом PostGIS, который вы хотите сохранить в базе данных. Если вы запустите свой проект с точкой останова и нажмете F6 для пошагового перехода внутри вашей Java-программы, вы увидите, когда будет выброшено исключение. Вы можете нажать F5, чтобы войти в любой метод, который хотите проверить. Посмотрите, как настроить удаленную отладку с помощью eclipse и используемого контейнера (Tomcat, JBoss, GlassFish и т. Д.). - person BendaThierry.com; 02.09.2012
comment
Хорошая точка зрения; когда Ру делал все за меня, я почти забыл об отладке. Думаю, это будет новый вопрос :(. - person orlade; 02.09.2012
comment
И вот он. Если бы я мог просто сохранить эту единственную цель, я был бы самым счастливым человеком в мире. Я бы назначил за это вознаграждение в 100 долларов, если бы мог. - person orlade; 02.09.2012
comment
Мне нравится щедрость - вы знаете, что такое шоколад и кокос: D. Вы дали мне идею для моего блога, и этого достаточно для моей помощи. - person BendaThierry.com; 02.09.2012
comment
Также будущие читатели заметят, что эти теги hibernate.cfg.xml должны находиться в пространстве имен hibernate, то есть hibernate.show_sql и т. Д. Для проектов Roo они входят в persistence.xml и нуждаются в включенном ведении журнала как минимум на уровне DEBUG. - person orlade; 04.09.2012
comment
Обратите внимание, что приведенное выше решение предназначено для спящего режима 4, если вы используете спящий режим 5, проверьте ответ pilladooo или мое объяснение - person Padvinder; 05.06.2019

Я решаю эту проблему, добавляя в application.properties такую ​​строку:

spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect
person pilladooo    schedule 06.07.2018
comment
Для меня это тоже решило проблему. У меня было hibernate.dialect=... вместо spring.jpa.properties.hibernate.dialect=... в application.properties. И столбец определяется так: @Column(columnDefinition = "GEOGRAPHY(POINT)") private com.vividsolutions.jts.geom.Point location; - person andy; 10.11.2018

Решение pilladooo работает с весенней загрузкой 2.0.3, спящим / пространственным 5.2.17.Final, Postgres 9.5.

Столбец в сущности в моем случае определяется как @Column (name = "geometry") private Geometry geometry;

и в базе данных как тип 'geometry' (чтобы избежать типа bytea, который автоматически генерируется в спящем режиме)

Сначала я решил «Обнаружено недопустимое значение флага порядка байтов», добавив columnDefinition = "geometry", но после этого спящий режим не прошел проверку схемы с помощью "Проверка схемы: обнаружен неправильный тип столбца в столбце [geometry] в таблице [my_shema.my_geometry_table]; найдено [геометрия (Типы # OTHER)], но ожидается [bytea (Типы # VARBINARY)] "

после добавления spring.jpa.properties.hibernate.dialect = org.hibernate.spatial.dialect.postgis.PostgisDialect, наконец, сработало. ColumnDefinition теперь тоже лишний

person Padvinder    schedule 05.06.2019

См. Также http://trac.osgeo.org/postgis/ticket/1830 An проблема возникла примерно во время выхода Postgresql 9xx и Postgis 2xx, который вызывал ту же ошибку «недопустимый конечный флаг» при использовании утилиты postgres pgsql2shp. Это можно исправить, удалив старые версии библиотеки libpq.so, так как это произошло из-за того, что Postgres изменил поведение bytea по умолчанию.

person John Powell    schedule 01.04.2013

После некоторой борьбы с данной проблемой, вот шаги, которые помогли мне ее решить. Прежде всего, я должен упомянуть, что использую сервер WildFly 17, PostgreSQL 12 и PostGIS 3.0.0. А теперь шаги, которые я считаю важными в этой проблеме:

Сделайте jboss-deployment-structure.xml файл в META-INF (если у вас его нет) и исключите спящий режим, который поставляется с 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>

Убедитесь, что ядро ​​гибернации и пространственная гибернация имеют одинаковую версию (используйте любую версию, которая вам нравится).

Ваш persistence.xml должен иметь собственность

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

И, наконец, я не думаю, что это очень важно, но я использовал org.locationtech.jts для геометрии в Java.

Надеюсь, я не пропустил ничего важного и что это обязательные шаги. Возможно, есть что-то еще, но прошло много часов, пробуя разные решения, и возможно, что я забыл включить какую-то зависимость / свойство. Ответ основан на личном опыте, поэтому не стесняйтесь комментировать, чтобы доказать свою неправоту или расширить ответ. Во всяком случае, я надеюсь, что кто-то сочтет этот ответ полезным.

person quepasa    schedule 19.02.2020