How to define Oracle Package Procedure in H2 for Testing

我们两清 提交于 2019-12-11 14:06:01

问题


I am testing an spring boot application that reads/writes data to an Oracle DB. This Oracle DB has Oracle packages and in those packages procedures. At some point, the spring boot application calls this procedure via a Entity Repository as follows

@Repository
public interface StudentRepository extends JpaRepository<Student, String> {

@Modifying
@Query(value = "begin sch1.STUDENT_PACKAGE.Set_Grades_To_A('A'); end;", nativeQuery = true)
public void setStudentGradeToA();
}

So, it uses a native query to make the call to to a procedure Set_GradesToA in the STUDENT_PACKAGE package of the sch1 schema.

I am currently testing the functionality of the Spring Boot application and NOT the integration between it and the Oracle database. Therefore, I have decided to use an in-memory database (H2) (with the Oracle compatibility option) to replace the Oracle DB for now. BUT how can I fake out these java package procedures?

I have tried creating an alias in my schema.sql (or data.sql) as follows:

CREATE SCHEMA if not exists sch1;
CREATE ALIAS sch1.STUDENT_PACKAGE AS $$ void Set_Grades_To_A(String s) { new String(s); } $$;

I really don't care what is inside the Set_Grades_To_A procedure what I care about is how to define it.

When I create the alias as above, I'm still getting a Syntax Error.

Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "BEGIN SCH1[*].STUDENT_PACKAGE.Set_Grades_To_A('A'); END; "; SQL statement:
begin sch1.STUDENT_PACKAGE.Set_Grades_To_A('A'); end; [42000-197]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.get(DbException.java:155)
    at org.h2.message.DbException.getSyntaxError(DbException.java:203)

I guess I have two questions:

  1. How can I fake out a stored procedure inside an Oracle package in the schema sch1?

  2. Why am I getting the Syntax Error above?


回答1:


Here is what I did.

Question #2: To answer this question I had to change the native query as follows

@Repository
public interface StudentRepository extends JpaRepository<Student, String> {

@Modifying
@Query(value = "call sch1.STUDENT_PACKAGE.Set_Grades_To_A('A')", nativeQuery = true)
public void setStudentGradeToA();
}

Question #1: Three things are involved to answer this. Now that I had changed the native query as above I got a different error:

Caused by: org.h2.jdbc.JdbcSQLException: Database "sch1" not found; SQL statement:
call sch1.STUDENT_PACKAGE.Set_Grades_To_A('A') [90013-197]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.get(DbException.java:155)

It was looking for a database called sch1. It seems like the pattern used to call a stored procedure in H2 is database.schema.procedure_name. Since I don't care what that procedure actually does I was able to fake this out by creating a database called sch1 a schema called STUDENT_PACKAGE and the procedure name Set_Grades_To_A

To create the in memory database, you have to set the following property spring.datasource.url in the application.properties file.

  1. Create the sch1 database as follows spring.datasource.url=jdbc:h2:mem:sch1;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle;INIT=CREATE SCHEMA IF NOT EXISTS first_schema. Notice the database name is sch1

  2. Create the STUDENT_PACKAGE schema by adding this \\;CREATE SCHEMA IF NOT EXISTS STUDENT_PACKAGE to the end of the spring.datasource.url. This adds a second schema called STUDENT_PACKAGE. The property should look like this spring.datasource.url=jdbc:h2:mem:sch1;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle;INIT=CREATE SCHEMA IF NOT EXISTS first_schema\\;CREATE SCHEMA IF NOT EXISTS STUDENT_PACKAGE

  3. Create a the Set_Grades_To_A stored procedure by adding this to your schema.sql CREATE ALIAS STUDENT_PACKAGE.Set_Grades_To_A AS $$ void setGradesToA(String s) { new StringBuilder(s).reverse().toString(); } $$;



来源:https://stackoverflow.com/questions/57062428/how-to-define-oracle-package-procedure-in-h2-for-testing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!