Spring(引导)使用 JPA/Hibernate 和 PostgreSQL - 对日期使用重叠

Spring(Boot) with JPA / Hibernate and PostgreSQL - use Overlaps for dates

所以我有一个项目,我们将 springBoot 和 PostgreSQL 10 与 PostGis 和 hibernate.spatial 一起用于空间查询。目前一切正常。

一个新的要求是查找开始结束日期以任何可能的方式与查询的开始结束日期重叠的实体(范围可能是封闭的、开始重叠的、中间的、结束重叠的)。

在 PostgreSQL 中,Overlaps 运算符似乎非常适合这项工作。

当尝试在我的 JPA 查询中使用它时,像这样的实体“Sth”..

select sth from Sth sth where 1=1 and (sth.start, sth.end) overlaps (:begin, :end)
// set begin and end params..

我得到其中之一..

antlr.NoViableAltException: unexpected token: overlaps

antlr.NoViableAltException: unexpected AST node: (

org.postgresql.util.PSQLException: FEHLER: rt_raster_from_wkb: wkb size (5)  < min size (61)

是否可以在不编写本机查询的情况下使用 JPA 的日期重叠?

看来您需要做三件事才能让它发挥作用。

  1. 可能无法将重叠用作运算符,但幸运的是它似乎也可以用作函数:overlaps(start1, end1, start2, end2)

  2. 重叠未被任何休眠核心 PostgreSQL[NN]方言映射。但是它 由 hibernate-spatial PostgisPG[NN] Dialects 映射的,它映射到 st_overlaps-function 用于空间重叠。所以你需要使用你自己的自定义方言来注册重叠函数,别名如下:


public class PostgisDialect extends org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect {

    public PostgisDialect() {
        super();
        registerFunction("dateoverlaps", new StandardSQLFunction("overlaps", StandardBasicTypes.BOOLEAN));
    }

}

并将其指定为您的spring.jpa.properties.hibernate.dialect(或spring.jpa.database-platform‍♂️)。

  1. 您的 JPA 查询必须包含这样的 = true

select sth from Sth sth where 1=1 and dateoverlaps(sth.start, sth.end, :begin, :end) = true

您可以通过使用 coalesce 函数来处理空值,即

select sth from Sth sth where 1=1 and dateoverlaps(coalesce(sth.start, sth.plannedStart), coalesce(sth.end, '3999-01-01'), :begin, :end) = true

当开始为空时使用 plannedStart,当结束为空/打开时使用未来长期日期。