【问题标题】:Stored procedure call with Spring JPA使用 Spring JPA 调用存储过程
【发布时间】:2021-03-15 09:36:30
【问题描述】:

我需要使用 JPA 调用存储过程。存储过程对多个表进行操作,并从这些表中返回一些列。

尝试使用@Procedure 似乎不起作用,在这种情况下始终找不到存储过程。

使用本机查询直接调用过程是成功的,但是使用这种方法,我需要将返回的结果映射到一个对象的列表。

我在存储库中的实现如下所示,

@Query(value = "EXECUTE dbs.multitable_Test :inputObj", nativeQuery = true)
List<sp> multitable_Test(@Param("inputObj")String inputObj);

存储过程返回的结果需要映射到sp类。

当我们在单个结果集中有多个表响应时,如何实现这一点?

已经尝试使用attributeConvert from this link,仍然出现以下异常。

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type

对此的任何帮助表示赞赏。

【问题讨论】:

  • 我认为存储过程不适合 JPA。
  • @duffymo 没有任何解决方法支持这个吗?
  • 我不知道。 JPA 是关系数据库之上的一层,它允许假装您只处理对象。存储过程不适合该模型。您已经在使用 Spring。只需使用 Spring JDBC 模板来管理它。

标签: java sql-server spring jpa jpql


【解决方案1】:

首先,这不是过程的真正用例。过程是为了修改数据库上的数据而没有任何返回值,那么你可以使用:

@Procedure(procedureName = "procedure_name")
void procedure(); // notice void

您应该使用functioncreate function 语法。函数可以修改数据并返回结果。

其次,如果您想将其映射到某个类,我看到了两种解决方案(使用EntityManager):

  1. 使用ResultTransformer

    entityManager.createNativeQuery(
        "select * from function_name(:parameter)"
    )
        .setParameter("parameter", parameter)
        .unwrap(org.hibernate.query.NativeQuery.class)
        .setResultTransformer(new ResultTransformer() {
            @Override
            public Object transformTuple(Object[] tuple, String[] aliases) {
                return new Sp(tuple[0]);
            }
    
            @Override
            public List transformList(List collection) {
                return collection;
            }
    
        })
        .getResultList();
    

    请注意,ResultTransformer 已被弃用,但功能如此强大,除非有合理的替代品,否则不会将其删除,请参阅 hibernate 开发人员的the note

  2. 使用ResultSetMapping。在实体上放置适当的注释:

    @SqlResultSetMapping(
        name = "sp_mapping",
        classes = @ConstructorResult(
            targetClass = Sp.class,
            columns = {
                @ColumnResult(name = "attribute", type = Long.class)
            })
    )
    

    并使用映射作为参数调用函数:

    entityManager.createNativeQuery(
        "select * " +
        "from function_name(:parameter);",
        "sp_mapping"
    )
        .setParameter("parameter", parameter)
        .getResultList();
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 2017-07-20
    • 2021-09-02
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多