使用 Spring JPA 调用存储过程
Posted
技术标签:
【中文标题】使用 Spring JPA 调用存储过程【英文标题】:Stored procedure call with 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 模板来管理它。 【参考方案1】:首先,这不是过程的真正用例。过程是为了修改数据库上的数据而没有任何返回值,那么你可以使用:
@Procedure(procedureName = "procedure_name")
void procedure(); // notice void
您应该使用function 和create function
语法。函数可以修改数据并返回结果。
其次,如果您想将其映射到某个类,我看到了两种解决方案(使用EntityManager
):
使用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。
使用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();
【讨论】:
以上是关于使用 Spring JPA 调用存储过程的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Data Jpa 在 Oracle 中调用存储过程时参数的数量或类型错误
Spring data jpa 调用存储过程处理返回参数及结果集
尝试使用 Spring Data JPA 运行存储过程时出现“类型不能为空”异常
使用 jparepository 调用存储过程 Spring Boot 应用程序