在 Oracle 和 H2 的@Formula 中使用 CURRENT_DATE()

Use CURRENT_DATE() in @Formula in Oracle and H2

我之前的问题因重复而被关闭

Use sysdate in @Formula in Oracle and H2

建议的解决方案:

How to use current date in H2 database SQL query

我试过了 CURRENT_TIMESTAMP:

@Formula("FLOOR(CURRENT_TIMESTAMP() - last_date)")
private Long daysSinceLastDate;

它正在与嵌入式 H2 数据库进行集成测试,但在 运行 应用程序 Oracle 中:

Caused by: java.sql.SQLException: ORA-30088: datetime/interval precision is out of range

CURRENT_TIMESTAMP() 在 Oracle 中根本不起作用,CURRENT_TIMESTAMP 在 H2 中不起作用。

如果您可以从当前来源构建 H2,则可以使用

CAST(CURRENT_DATE - LAST_DATE AS INT)

或 Oracle 特定

FLOOR(SYSDATE - LAST_DATE)

来自您之前的问题。

Oracle 18c 也接受这两种变体。

您可以在 GitHub:

上获取 H2 的来源

https://github.com/h2database/h2database

按照此处所述使用 jar 目标:

https://h2database.com/html/build.html#building

不要使用 H2 的 Maven 构建,它只是实验性的。

我已经结束了在集成测试数据源配置中添加拦截器。

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setDatabase(Database.H2);
    vendorAdapter.setGenerateDdl(false);
    vendorAdapter.setShowSql(true);

    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);

    Properties properties = new Properties();
    properties.setProperty(Environment.FORMAT_SQL, "false");
    **properties.put(Environment.INTERCEPTOR, hibernateInterceptor());**
    entityManagerFactoryBean.setJpaProperties(properties);

    return entityManagerFactoryBean;
}

@Bean
public EmptyInterceptor hibernateInterceptor() {
    return new EmptyInterceptor() {
        @Override
        public String onPrepareStatement(String sql) {
            String query = super.onPrepareStatement(sql);
            query = query.replace("projaudit0_.sysdate", "CURRENT_DATE()");
            return query;
        }
    };
}

我在@Where 子句中遇到了同样的问题。我需要像

这样的东西
@Entity
@Where(clause = "open_date <= current_date")
public class SomeEntity {

    // omitted

}

并且由于 Oracle 和 H2 都具有输入精度为 current_timestamp 的函数,因此

@Entity
@Where(clause = "open_date <= current_timestamp(6)")
public class SomeEntity {

    // omitted

}

对我有用。这里的6是默认值,所以相当于Oracle中的current_timestamp和H2中的current_timestamp()