Spring Data JPA NamedStoredProcedureQuery 多个输出参数

Posted

技术标签:

【中文标题】Spring Data JPA NamedStoredProcedureQuery 多个输出参数【英文标题】:Spring Data JPA NamedStoredProcedureQuery Multiple Out Parameters 【发布时间】:2015-07-06 02:40:25 【问题描述】:

我有一个简单的存储过程,用于测试 Spring Data JPA 存储过程功能。

create or replace procedure plus1inout (arg in int,res1 out int,res2 out int) is
BEGIN   
 res1 := arg + 1; 
 res2 := res1 + 1;
END;

我的代码是:

@Repository
public interface AdjudConverDateSPRepository extends JpaRepository<AdjudConverDateSP, Long> 
    @Procedure(name = "plus1")
    Object[] plus1(@Param("arg") Integer arg);


@Entity
@NamedStoredProcedureQuery(name = "plus1", procedureName = "ADJUD.PLUS1INOUT",
        parameters = 
        @StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "res1", type = Integer.class),
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "res2", type = Integer.class)
)
public class AdjudConverDateSP implements Serializable 
        //stub to satisfy hibernate identifier requirement
        @Id @GeneratedValue
        private Long id;


当我有一个 OUT 参数时,一切正常。但是,一旦我添加了第二个 OUT 参数,我就会得到一个异常,说它在实体中找不到该过程。

Caused by:
  org.springframework.data.mapping.PropertyReferenceException: No property plus1 found for type AdjudConverDateSP!  at
  org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75) at 
  org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327) at
  org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307) at
  org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270) at
  org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241) at
  org.springframework.data.repository.query.parser.Part.<init>(Part.java:76) at
  org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235) at
  org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373) at
  org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353)

【问题讨论】:

您使用的是哪个 Spring Data JPA 版本? Spring-Data JPA 1.8.0 版 这个github.com/spring-projects/spring-data-examples/issues/80 的git repo 中有一个问题......当他们得到它时这将是答案。 您能否尝试将@Procedure(name = "plus1") 替换为@Procedure("plus1inout")@Procedure(procedureName="plus1inout") @HowardWang 评论帮助我解决了类似的错误。我在 (name="proc") 下给出了名字,但是当我给出 @Procedure("proc") 时它起作用了。奇怪! 【参考方案1】:

大家好,基于Jeff Sheetsanwer 解决了我的问题,所以我也想提供一点帮助

这是我的解决方案

CREATE PROCEDURE `cardById`(IN id int, out cardNumber varchar(16), out personId bigint)
BEGIN
    SELECT card_number, person_id into cardNumber, personId 
    FROM cards 
    WHERE card_number = id
    LIMIT 1;
END

在实体类中

@NamedStoredProcedureQuery(name = "Card.cardById",
    procedureName = "cardById", parameters = 
    @StoredProcedureParameter(mode = ParameterMode.IN, name = "id", type = String.class),
    @StoredProcedureParameter(mode = ParameterMode.OUT, name = "cardNumber", type = String.class),
    @StoredProcedureParameter(mode = ParameterMode.OUT, name = "personId", type = Long.class)

在仓库中

@Procedure(name = "Card.cardById")
Map<String, Object> cardById(String id);

编码愉快!

【讨论】:

【参考方案2】:

Spring Data JPA 支持多个输出参数。 Method 的返回类型必须是 Map。我花了很多时间在这上面。下面的链接正好给出了这个例子,搜索 User.plus1IO2。

User.java

UserRepository.java

【讨论】:

【参考方案3】:

您可以在@Procedure 注释中使用outputParameterName 参数指定返回多个输出参数之一,如下所示:

@Repository
public interface AdjudConverDateSPRepository extends JpaRepository<AdjudConverDateSP, Long> 
    @Procedure(name = "plus1", outputParameterName = "res2")
    Integer plus1(@Param("arg") Integer arg);

2019 年 6 月 24 日更新:

Spring Data JPA 2.2-RC1 现在支持多个输出参数 https://spring.io/blog/2019/06/17/spring-data-moore-rc1-and-lovelace-sr9-released

https://jira.spring.io/browse/DATAJPA-707

接口方法只需要有一个 Map 返回类型,所以每个输出参数都可以通过键名访问:

@Repository
public interface AdjudConverDateSPRepository extends JpaRepository<AdjudConverDateSP, Long> 
    @Procedure(name = "plus1")
    Map<String, Object> plus1(@Param("arg") Integer arg);

【讨论】:

杰夫,我正在尝试关注此链接jira.spring.io/browse/DATAJPA-707,但我无法获得来自哪个 jar @Outparameters 注释。我正在使用最新的 spring-boot-starter-parent 2.2.5 版本。你能告诉我需要罐子的信息吗?谢谢 @Khushi,我认为原始描述有点过时了。我相信您可以像这样使用@StoredProcedureParameter 指定github.com/spring-projects/spring-data-jpa/blob/master/src/test/… 谢谢杰夫,我已经发布了一个关于存储过程***.com/questions/61454441/… 的问题。请您检查并回复一次。谢谢【参考方案4】:

Spring 目前还不支持多个输出参数。为此有一个JIRA。

【讨论】:

这应该是一条评论,因为它没有完全回答 OP 的问题【参考方案5】:

看起来@Procedure 只需要一个直接绑定到方法返回类型的 OUT 参数...

要处理多个 OUT 参数,您可以直接使用 JPA API:

StoredProcedureQuery proc = em.createNamedStoredProcedureQuery("plus1");

proc.setParameter("arg", 1);
proc.execute();
Integer res1 = (Integer) proc.getOutputParameterValue("res1");
Integer res2 = (Integer) proc.getOutputParameterValue("res2");
...

【讨论】:

最终使用 JPA API 是我所做的。您在哪里发现 @Procedure 只需要一个 OUT 参数? API 仅包含一个 OUT 参数docs.spring.io/spring-data/jpa/docs/current/api/org/… 您能否提供完整的示例。我是新手,无法通过实体管理器调用命名存储过程。

以上是关于Spring Data JPA NamedStoredProcedureQuery 多个输出参数的主要内容,如果未能解决你的问题,请参考以下文章

spring-data详解之spring-data-jpa:简单三步快速上手spring-data-jpa开发

spring data jpa怎么和solr整合

spring data jpa问题

Spring Data 系列 Spring+JPA(spring-data-commons)

spring-data-jpa软删除方案

spring data jpa 详解