首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Spring/Hibernate/JPA中正确调用PostgreSQL函数(存储过程)?

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

Stack Overflow用户
提问于 2014-09-30 22:01:28
回答 6查看 28.7K关注 0票数 9

我使用的是Spring MVC4、Hibernate和Postgres9.3,并在PostgreSQL中定义了如下函数(存储过程):

代码语言:javascript
复制
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;

如果我像这样在pgAdmin中运行这个函数,它工作得很好:

代码语言:javascript
复制
select spa.create_tenant('somename');

现在,我尝试从我的服务中运行这个函数,如下所示:

代码语言:javascript
复制
@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();
}

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

代码语言:javascript
复制
javax.persistence.PersistenceException: org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111

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

代码语言:javascript
复制
RETURNS character varying AS

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

代码语言:javascript
复制
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Error calling CallableStatement.getMoreResults

有人知道这是怎么回事吗?知道如何在PostgreSQL中正确调用存储过程吗?

EN

回答 6

Stack Overflow用户

发布于 2018-08-16 20:50:16

如果您还在使用spring数据,则只需在@Repository接口中定义一个过程,

代码语言:javascript
复制
@Procedure(value = "spa.create_tenant")
public void createTenantOrSomething(@Param("t_name") String tNameOrSomething);

有关详细信息,请参阅docs

票数 5
EN

Stack Overflow用户

发布于 2015-01-02 22:04:17

在实体类中,定义一个NamedNativeQuery,就像使用select调用postgresql函数一样。

代码语言:javascript
复制
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.Entity;
@NamedNativeQueries(
    value={
            // cast is used for Hibernate, to prevent No Dialect mapping for JDBC type: 1111
            @NamedNativeQuery(
                  name = "Tenant.createTenant",
                 query = "select cast(create_tenant(?) as text)"
            )
     }
)
@Entity
public class Tenant

hibernate不能映射void,因此解决方法是将结果转换为文本

代码语言:javascript
复制
public void createSchema(String name) {
    Query query = em.createNamedQuery("Tenant.createTenant")
            .setParameter(1, name);
    query.getSingleResult();
}
票数 3
EN

Stack Overflow用户

发布于 2014-10-01 14:59:02

由于您使用的是PostgreSQL,因此您可以在中调用任何类型为function的存储过程(否则,SELECT将只允许您执行在selects中声明为只读的函数)。

您可以使用EntityManager.createNativeQuery(SQL)

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26122796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档