在第四次阅读 Vlad Mihalcea great post 之后,我意识到如何使用 JPA 的标准构建器实现相同的结果:
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 $1 at time zone $2;'
language sql;
我通过使用以下类公开休眠:
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>