2016-01-19 4 views
1

Я использую Hibernate Spatial verion 5.0.7.Final как ORM. Иногда, когда я выполнить запрос, используя геометрию в качестве имени параметра я получаю следующее исключение:HibernateException: позиции коллинеарны в 2D

org.hibernate.HibernateException: Positions are collinear in 2D 

Я понимаю, что иногда мои геометрий коллинеарны и NumericalMethods модуль в Geolatte библиотеки проверки, является ли мой геометрии isCounterClockwise, что поднимет это исключение.

Интересно, почему это делается, но более того, Что я могу сделать, чтобы избежать этого? Ошибка.

Код Hibernate под номером NumericalMethods.java проверяет только первые три координаты. В моем случае иногда эти три первые координаты являются коллинеарными, а четвертый - допустимым полигоном. Я не могу понять, почему он не будет перебирать остальные координаты, чтобы определить, является ли он isCounterClockwise или нет.

Полный StackTrace:

org.hibernate.HibernateException: Positions are collinear in 2D 
at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.toNative(SDOGeometryValueBinder.java:71) 
at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.bind(SDOGeometryValueBinder.java:52) 
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:257) 
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:252) 
at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:52) 
at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:627) 
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1944) 
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1897) 
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1875) 
at org.hibernate.loader.Loader.doQuery(Loader.java:919) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) 
at org.hibernate.loader.Loader.doList(Loader.java:2611) 
at org.hibernate.loader.Loader.doList(Loader.java:2594) 
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2423) 
at org.hibernate.loader.Loader.list(Loader.java:2418) 
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371) 
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) 
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1326) 
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87) 
+0

Я только что видел, что есть текущий билет: https://hibernate.atlassian.net/browse/HHH-10410 Может быть, люди спячки могут что-то с этим поделать, или между тем я могу найти обходное решение. – krause

ответ

1

Как прокомментировал, похоже, что это ошибка в Hibernate. При попытке создать многоугольник с колинейными широтами спящий пространственный объект бросает исключение. Он был зарегистрирован как билет Jira:

https://hibernate.atlassian.net/browse/HHH-10410

Похоже, что преступник является isCounterClockwise функция NumericalMethods.java, библиотека Geolatte. Вероятно, это происходит с первой версии Hibernate 5.

Если кому-то это будет полезно, я вставлю ниже кода, чтобы создать собственную версию этой библиотеки, которая предотвратит эту ошибку. Я также отправить запрос тянуть в случае, если они считают ее слияние (или нечто подобное) к своему хозяину:

https://github.com/GeoLatte/geolatte-geom/pull/43

/** 
* Determines whether the specified {@code PositionSequence} is counter-clockwise. 
* <p/> 
* <p>Only the first three positions, are inspected to determine whether the sequence is counter-clockwise. 
* In case are less than three positions in the sequence, the method returns true.</p> 
* 
* @param positions a {@code PositionSequence} 
* @return true if the positions in the specified sequence are counter-clockwise, or if the sequence contains 
* less than three elements. 
*/ 
public static boolean isCounterClockwise(PositionSequence<?> positions) { 
    if (positions.size() < 3) return true; 
    Position p0 = positions.getPositionN(0); 
    Position p1 = positions.getPositionN(1); 
    double det = 0; 
    int positionsSize = positions.size(); 
    int i = 2; 
    while(i < positionsSize && det == 0) { 
     Position p2 = positions.getPositionN(i); 
     det = deltaDeterminant(p0, p1, p2); 
     i++; 
    } 
    if (det == 0) { 
     throw new IllegalArgumentException("Positions are collinear in 2D"); 
    } 
    return det > 0; 
} 

Update: запрос втягивания был слит в мастер, так что это будет будет выпущен в конце концов.