如何在Spring/Hibernate/JPA中正确调用PostgreSQL函数(存储过程)?

Mir*_*vic 5 postgresql spring hibernate jpa

我正在使用Spring MVC 4,Hibernate和PostgreSQL 9.3,并在Postgres中定义了函数(存储过程),如下所示:

CREATE OR REPLACE FUNCTION spa.create_tenant(t_name character varying)
  RETURNS void AS
  $BODY$
    BEGIN
      EXECUTE format('CREATE SCHEMA IF NOT EXISTS %I AUTHORIZATION postgres', t_name);
    END
  $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION spa.create_tenant(character varying)
OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)

如果我像这样在pgAdmin中运行此函数它工作正常:

select spa.create_tenant('somename');
Run Code Online (Sandbox Code Playgroud)

现在我正试图从我的服务运行这个功能,如下所示:

@Override
@Transactional
public void createSchema(String name) {
    StoredProcedureQuery sp = em.createStoredProcedureQuery("spa.create_tenant");
    sp.registerStoredProcedureParameter("t_name", String.class, ParameterMode.IN);
    sp.setParameter("t_name", name);
    sp.execute();
}
Run Code Online (Sandbox Code Playgroud)

如果我运行我的方法,我会收到以下错误:

javax.persistence.PersistenceException: org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111
Run Code Online (Sandbox Code Playgroud)

我猜这是因为在函数中定义的返回类型void所以我将返回类型更改为如下所示:

RETURNS character varying AS
Run Code Online (Sandbox Code Playgroud)

如果我再次运行我的方法,我会得到这个例外:

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Error calling CallableStatement.getMoreResults
Run Code Online (Sandbox Code Playgroud)

有谁知道这里发生了什么以及如何正确调用PostgreSQL中的存储过程,即使返回类型为void?

Geo*_*lou 5

如果您还使用弹簧数据,您可以@Repository像这样在界面中定义一个过程,

@Procedure(value = "spa.create_tenant")
public void createTenantOrSomething(@Param("t_name") String tNameOrSomething);
Run Code Online (Sandbox Code Playgroud)

文档中的更多内容。


Dan*_*lor 1

由于您使用的是PostgreSQL,因此您可以像您已经编写的那样调用任何类型为 function 的存储过程(OracleSELECT,否则,将允许您只执行在选择中声明为只读的函数)。

您可以使用EntityManager.createNativeQuery(SQL)

由于您使用的是 Spring,因此您SimpleJdbcTemplate.query(SQL)也可以用来执行任何 SQL 语句。