hibernate - 创建函数 - UncategorizedScriptException - ArrayIndexOutOfBoundsException

标签 hibernate postgresql function spring-boot

描述

我作为 Spring Boot 项目的新成员工作,该项目使用 2 个不同的属性文件来实现与数据库设置相关的 2 个不同配置:

  • 生产模式:postgres SQL DB
  • 开发方式:内存DB中的h2

由于我试图尽量减少这两个脚本中的差异,我已经开始编写函数来处理与日期/时间处理相关的差异。

一个例子是添加小时数,因为 postgres 使用时间间隔,而 h2 使用 oracle 类似的 date_add 函数。

不幸的是,在控制台中运行的函数创建语句出现异常。

现有文件

配置/属性

spring.profiles.active=pre-prod

spring.datasource.url=jdbc:postgresql://localhost:5432/db
spring.datasource.username=postgres
spring.datasource.password=root
spring.datasource.driver-class-name=org.postgresql.Driver

spring.datasource.data=classpath:db/migration/postgres/db_functions.sql,classpath:db/migration/postgres/data.sql
spring.jpa.hibernate.ddl-auto=create

db_functions.sql

--Adds a cast to date to the specific statement
--for h2 simply make a wrapper
CREATE OR REPLACE FUNCTION db_pgres_cast_varchar_to_date(d VARCHAR ) RETURNS date AS $$
        BEGIN
                RETURN d::date;
        END;
$$ LANGUAGE plpgsql;

--Common function for h2 and vct to add hours
--References: http://stackoverflow.com/questions/9376350/postgresql-how-to-concat-interval-value-2-days
CREATE OR REPLACE FUNCTION db_add_hours(d timestamp, hours int) RETURNS timestamp AS $$
        BEGIN
                RETURN d +  (hours || ' hours')::interval;
        END;
$$ LANGUAGE plpgsql;

异常

NFO] org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor Shutting down ExecutorService 'createTaskExecutor'
Exception in thread "main" org.springframework.jdbc.datasource.init.UncategorizedScriptException: Failed to execute database script from resource [class path resource [db/migration/postgres/vct_functions.sql]]; nested exception is java.lang.ArrayIndexOutOfBoundsException
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:509)

更新

我开始调试,发现我的脚本被解释为 6 个 SQL 命令,而不是拆分/解析器代码创建 2 个语句:

enter image description here

更新2

问题似乎出在splitSqlScript的实现上,定义:

public static void splitSqlScript(EncodedResource resource, String script, String separator, String commentPrefix,
            String blockCommentStartDelimiter, String blockCommentEndDelimiter, List<String> statements)
            throws ScriptException

https://www.codatlas.com/github.com/spring-projects/spring-framework/HEAD/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java?line=166

更新3

由于 Spring Utils of Spring 似乎是问题所在,我正在尝试使用不同的语法来创建我的函数:

--Adds a cast to date to the specific statement
--for h2 simply a wrapper
CREATE OR REPLACE FUNCTION vct_pgres_cast_varchar_to_date(VARCHAR ) RETURNS date
    AS 'select $1::date;'
    LANGUAGE SQL
    RETURNS NULL ON NULL INPUT;


--Common function for h2 and vct to add hours
--References: http://stackoverflow.com/questions/9376350/postgresql-how-to-concat-interval-value-2-days

CREATE OR REPLACE FUNCTION vct_add_hours(timestamp, integer) RETURNS timestamp
    AS 'select $1 +  ($2 || '' hours'')::interval'
    LANGUAGE SQL
    RETURNS NULL ON NULL INPUT;

最佳答案

问题是spring的SplitSqlScript:https://www.codatlas.com/github.com/spring-projects/spring-framework/HEAD/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java?line=166

我通过更改我的 create function 语句的语法来避免 $$ 并将 SQL 语句括在引号中来解决这个问题。

例如

CREATE OR REPLACE FUNCTION vct_pgres_cast_varchar_to_date(VARCHAR ) RETURNS date
    AS 'select $1::date;'
    LANGUAGE SQL
    RETURNS NULL ON NULL INPUT;

关于hibernate - 创建函数 - UncategorizedScriptException - ArrayIndexOutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33144038/

相关文章:

java - org.hibernate.util.JDBCExceptionReporter - 'postalCode' 中的未知列 'field list'

postgresql - 按关联查询和对模型的影响

postgresql - 使用 docker-compose 在 postgresql 数据库中创建表

javascript onclick,匿名函数

javascript - 如何调用一个函数来重新加载另一个函数(例如在 "orientationchange()"上)?

java - 让 JPA 生成具有指定行格式的表

java.lang.ClassNotFoundException : org. hibernate .bytecode.instrumentation.internal.FieldInterceptionHelper

sql - Postgres - 如何检查空数组

bash - 如何从函数内部确定函数名称

java - GWT 服务器端与数据库的交互