如何在 Jpa 标准中移植 postgresql 时区语句

How to port postgresql time zone statement in Jpa criteria

JPA/Hibernate 标准的新手,我正在使用 Postgresql。我必须翻译这样的东西:

SELECT * from mytable m where m.mytimestamptzcolum at time zone m.mytimezonecolumn < ?;

在 JPA 标准中,但在与 CriteriaBuilder 和自定义函数搞乱了一整天后,我还没有找到解决方案。 Hibernate 有很好的 org.hibernate.criterion.Restrictions#sqlRestriction 但我不得不留在 JPA 上。建议?

在第四次阅读伟大的 Vlad Mihalcea post 之后,我意识到如何使用 JPA 的 criteriabuilder 获得相同的结果:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyTable> query = cb.createQuery(MyTable.class);
Root<MyTable> root = query.from(MyTable.class);

Predicate exp = cb.lessThan(cb.function("get_time_at_zone", Timestamp.class,
  root.get(MyTableMetamodel_.since).get(MyEmbeddedLocalDateTime_.instant),
  root.get(MyTableMetamodel_.since).get(MyEmbeddedLocalDateTime_.zoneId)),
  Timestamp.valueOf(time));

以上代码依赖于我添加的这个自定义函数:

CREATE FUNCTION get_time_at_zone(timetoconvert timestamptz, zoneid character varying) RETURNS timestamp AS
  'select  at time zone ;'
language sql;

我通过使用以下 class:

来休眠
public class FunctionCastToSpecificTimezone implements MetadataBuilderContributor {

@Override
public void contribute(MetadataBuilder metadataBuilder) {
    metadataBuilder.applySqlFunction(
            "get_time_at_zone",
            new StandardSQLFunction(
                    "get_time_at_zone",
                    StandardBasicTypes.TIMESTAMP));
    }
}

并注册到persistence.xml

<persistence-unit name="puname">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    ...
    <properties>
        ...
        <property name="hibernate.metadata_builder_contributor"
            value="my.dummy.sql.utils.FunctionCastToSpecificTimezone" />
    </properties>
</persistence-unit>