java - Hibernate异常: Positions are collinear in 2D

标签 java hibernate spatial hibernate-5.x hibernate-spatial

我使用 Hibernate Spatial 版本 5.0.7.Final 作为 ORM。有时,当我使用几何图形作为命名参数执行查询时,会出现以下异常:

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

我知道有时我的几何图形是共线,并且 Geolatte 库中的 NumericalMethods 模块正在检查我的几何图形是否isCounterClockwise,它会引发此异常。

我想知道为什么它会这样做,但更重要的是,我可以做些什么来避免这个错误。

NumericalMethods.java 下面的 Hibernate 代码仅检查前三个坐标。就我而言,有时这三个第一个坐标是共线的,但第四个坐标将使其成为有效的多边形。我不明白为什么它不会迭代其余的坐标来判断它是否是逆时针的。

完整堆栈跟踪:

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)

最佳答案

正如评论所述,它看起来像是 Hibernate 中的一个错误。当尝试创建具有共线纬度的多边形时, hibernate 空间会引发异常。它已注册为 Jira 票证:

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

看起来罪魁祸首是 Geolatte 库 NumericalMethods.java 中的 isCounterClockwise 函数。可能自 Hibernate 5 第一个版本以来就发生了这种情况。

如果有人发现它有用,我将在代码下方粘贴以创建您自己的该库的自定义版本,以防止此错误发生。我还会提交一个拉取请求,以防他们考虑将其(或类似的东西)合并到他们的 master 中:

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;
}

更新:拉取请求已合并到master中,因此最终将被发布。

关于java - Hibernate异常: Positions are collinear in 2D,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34884955/

相关文章:

java - 关于Spatial4J中距离计算的一个问题

sql-server - Geoserver 无法识别空间列

java - java中的RMI聊天程序 - 如何从客户端向客户端发送消息(不通过服务器)?

java - 访问 HashMap 中数组列表中的值并编辑该值

java - JPA- hibernate : UniqueConstraint on OneToOne & ManyToOne JoinColumns

java - 在 SQL Server 中使用 UTC 时间保存当前日期时出现问题

algorithm - 空间数据结构中的不同搜索方法

java - 使用 hamcrest contains() 方法比较两个集合

java - 如何让 sbt 在发布到 Maven 存储库时用实际日期替换 SNAPSHOT?

Hibernate更新主键,批量更新从update [0]返回意外的行数;实际行数 : 0; expected: 1