spring-data-jpa 已命名存储过程查询输出Map〈键,实体>

yacmzcpb  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(177)

我正在使用Spring Data JPA NamedStoredProcedureQuery从过程Oracle数据库中输出多个参数
在实体类中:

@NamedStoredProcedureQuery(name = "Ent.getCust", resultClasses = CustomerEntity.class, 
            procedureName = "pkg.p_get_cust", parameters = {
            @StoredProcedureParameter(mode = ParameterMode.IN, name = "p_username", type = String.class),
            @StoredProcedureParameter(mode = ParameterMode.OUT, name = "o_local_code", type = String.class),
            @StoredProcedureParameter(mode = ParameterMode.REF_CURSOR, name = "o_result", type = Void.class) }) })

在存储库界面中

@Repository
public interface CustomerRepositoryExt extends JpaRepository<CustomerEntity, Long> {

   @Procedure(name = "Ent.getCust")
   Map<String, CustomerEntity> getCust(@Param("p_username") String username);
}

当前此代码返回错误:

org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class oracle.jdbc.OracleConnection]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: java.util.HashMap["o_result"]->oracle.jdbc.driver.ForwardOnlyResultSet["statement"]->oracle.jdbc.driver.T4CStatement["connection"]->oracle.jdbc.driver.T4CConnection["wrapper"])
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:460)
    at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290)

我不知道,Spring Data JPA支持是否可以返回此结果?

eni9jsuy

eni9jsuy1#

我不认为java对象类型直接支持oracle输出类型(我自己尝试了很多次,但都是徒劳的)。您可能试图直接将o_result refcursorMap到CustomerEntity,这不是一个好主意。我宁愿建议使用老派的方法,使用entityManager.createStoredProcedureQuery来进行oracle过程调用。
它看起来像这样:使用您的过程名称定义StoredProcedureQuery并将输出refcursor和字符串参数o_local_code注册为ResultSet对象。

storedProcedureQuery.registerStoredProcedureParameter("o_result", void.class, ParameterMode.REF_CURSOR);
storedProcedureQuery.registerStoredProcedureParameter("o_local_code", String.class, ParameterMode.OUT); 
ResultSet rs = (ResultSet)storedProcedureQuery.getOutputParameterValue("o_result");

循环遍历结果集并构建CustomerEntity。这样做的一个很好的理由是能够从多行refcursor构建List<CustomerEntity>(如果它确实返回多行)。

相关问题