简体   繁体   English

Spring Boot invalidDataAccessApiUsageException - OUT/INOUT 参数不可用

[英]Spring Boot invalidDataAccessApiUsageException - OUT/INOUT Parameter is not available

i'm using an Oracle stored procedure in Spring Boot which has some IN/OUT parameters.我在 Spring Boot 中使用了一个 Oracle 存储过程,它有一些 IN/OUT 参数。

When i'm getting an out parameter it throws an exception invalidDataAccessApiUsageException: OUT/INOUT Parameter is not available: ent_mensaje.当我得到一个 out 参数时,它会抛出一个异常invalidDataAccessApiUsageException: OUT/INOUT Parameter is not available: ent_mensaje.

This is the stored procedure definition这是存储过程定义

create or replace PROCEDURE     fon_anula_programacion (
   ent_numero_operacion   IN       NUMBER,
   ent_numero_fisico      IN       VARCHAR2,
   ent_mensaje            IN OUT   VARCHAR2,
   ent_canal_origen       IN OUT   VARCHAR2,
   ent_senal_proceso      IN OUT   VARCHAR2,
   ent_senal_commit       IN OUT   VARCHAR2,
   ent_sw_pos             IN OUT   NUMBER
) IS
...

Entity class whit its @NamedStoredProcedureQuery实体 class 及其@NamedStoredProcedureQuery

@Getter
@Setter
@Entity
@NoArgsConstructor
@NamedStoredProcedureQueries({
        @NamedStoredProcedureQuery(name = "Valores.AnularAdicionFondoSif",
                procedureName = "FON.FON_ANULA_PROGRAMACION",
                resultClasses = DTOAnularAdicionSIF.class,
                parameters = {
                        @StoredProcedureParameter(name = "ent_numero_operacion", type = BigDecimal.class, mode = ParameterMode.IN),
                        @StoredProcedureParameter(name = "ent_numero_fisico", type = String.class, mode = ParameterMode.IN),
                        @StoredProcedureParameter(name = "ent_mensaje", type = String.class, mode = ParameterMode.INOUT),
                        @StoredProcedureParameter(name = "ent_canal_origen", type = String.class, mode = ParameterMode.INOUT),
                        @StoredProcedureParameter(name = "ent_senal_proceso", type = String.class, mode = ParameterMode.INOUT),
                        @StoredProcedureParameter(name = "ent_senal_commit", type = String.class, mode = ParameterMode.INOUT),
                        @StoredProcedureParameter(name = "ent_sw_pos", type = BigDecimal.class, mode = ParameterMode.INOUT)
                }
        )
})
public class DTOAnularAdicionSIF {
    @Id
    @Column
    private BigDecimal Numero_operacion;
    @Column
    private String Numero_fisico;
    @Column
    private String Mensaje;
    @Column
    private String Canal_origen;
    @Column
    private String Senal_proceso;
    @Column
    private String Senal_commit;
    @Column
    private BigDecimal Sw_pos;
}

My Params class我的参数 class

public class AnularAdicionSIFParameters {
    @Params(name = "ent_numero_operacion",direction = Params.Direction.IN)
    private BigDecimal Numero_operacion;

    @Params(name = "ent_numero_fisico",direction = Params.Direction.IN)
    private String Numero_fisico;

    @Params(name = "ent_mensaje",direction = Params.Direction.INOUT)
    private String Mensaje;

    @Params(name = "ent_canal_origen",direction = Params.Direction.INOUT)
    private String Canal_origen;

    @Params(name = "ent_senal_proceso",direction = Params.Direction.INOUT)
    private String Senal_proceso;

    @Params(name = "ent_senal_commit",direction = Params.Direction.INOUT)
    private String Senal_commit;

    @Params(name = "ent_sw_pos",direction = Params.Direction.INOUT)
    private BigDecimal Sw_pos;
}

Sending parameters发送参数

AnularAdicionSIFParameters anularAdicionSIFParameters = AnularAdicionSIFParameters.builder()
.Numero_operacion(BigDecimal.valueOf(Double.parseDouble(comprobante)))
                .Numero_fisico(numerofisico)
                .Senal_commit("S")
                .Canal_origen(canal)
                .Senal_proceso("S")
                .Mensaje("")
                .Sw_pos(BigDecimal.valueOf(0))
                .build();
String response = repository.AnularAdicionReturnMensaje(anularAdicionSIFParameters);

Repository method存储库方法

public String AnularAdicionReturnMensaje(AnularAdicionSIFParameters parameters) throws IllegalAccessException{
        String name_procedure = "Valores.AnularAdicionFondoSif";
//super is the class who set the parameters and execute the procedure
        ResponseProcedure<AnularAdicionSIF> respuestaSif = super.runNamedStoredProcedure(name_procedure,parameters);
        return respuestaSif.getOutput().get("ent_mensaje").toString();
    }

Setting the parameters and executing the procedure设置参数并执行程序

public ResponseProcedure<E> runNamedStoredProcedure(String nameProcedure, Object params) throws IllegalAccessException {
        StoredProcedureQuery storedProcedureQuery = em.createNamedStoredProcedureQuery(nameProcedure);
        Map<String, Object> output = new HashMap<>();

        Class<?> objectClass = params.getClass();

        Field[] extend = objectClass.getSuperclass().getDeclaredFields();
        Field[] base = objectClass.getDeclaredFields();
        Field[] allFields = new Field[extend.length + base.length];
        Arrays.setAll(allFields, i ->
                (i < extend.length ? extend[i] : base[i - extend.length]));


        for (Field field: allFields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(Params.class)) {
                Params param = field.getAnnotation(Params.class);
                if(param.direction() == Params.Direction.IN || param.direction() == Params.Direction.INOUT)
                    storedProcedureQuery.setParameter(param.name(), (field.get(params) != null ) ? field.get(params) : "");
            }
        }

        storedProcedureQuery.execute();

        Arrays.stream(allFields).filter(field -> (field.getAnnotation(Params.class).direction() == Params.Direction.OUT || field.getAnnotation(Params.class).direction() == Params.Direction.INOUT))
                .forEach(ff ->{
                    Params param = ff.getAnnotation(Params.class);
                    output.put(param.name(), storedProcedureQuery.getOutputParameterValue(param.name()));
                });

        return new ResponseProcedure<E>(toList(storedProcedureQuery.getResultList()), output);
    }

And the error: OUT/INOUT parameter not available: ent_mensaje; nested exception is java.lang.IllegalArgumentException: OUT/INOUT parameter not available: ent_mensaje并且错误: OUT/INOUT parameter not available: ent_mensaje; nested exception is java.lang.IllegalArgumentException: OUT/INOUT parameter not available: ent_mensaje OUT/INOUT parameter not available: ent_mensaje; nested exception is java.lang.IllegalArgumentException: OUT/INOUT parameter not available: ent_mensaje

I fixed by adding @Transactional to the method that performs the call to repository.我通过将@Transactional 添加到执行对存储库的调用的方法来修复。 like @Parawata comments in this answer喜欢这个答案中的@Parawata评论

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 invalidDataAccessApiUsageException - OUT/INOUT 参数不可用。 从 springboot 1.5.7 升级到 2.1.6 和 hibernate 5.3 - invalidDataAccessApiUsageException - OUT/INOUT Parameter is not available. Upgrading from springboot 1.5.7 to 2.1.6 and hibernate 5.3 带有 Spring boot jpa 错误的 SQL 服务器过程调用:“无法提取 OUT/INOUT 参数值” - SQL server procedure call with Spring boot jpa error: "Unable to extract OUT/INOUT parameter value" Spring引导使用Set - InvalidDataAccessApiUsageException进行存储库查询 - Spring boot Repository query using Set - InvalidDataAccessApiUsageException Spring:InvalidDataAccessApiUsageException? - Spring: InvalidDataAccessApiUsageException? .... Spring Boot 中构造函数的参数 0 - Parameter 0 of constructor in .... Spring Boot 构造函数的参数 0 … Spring Boot - Parameter 0 of constructor in … Spring Boot WebServices中的Inout和Out参数 - Inout and Out parameters in WebServices Spring Boot静态资源不可用 - Spring Boot static resources are not available 使用存储库的异步方法中的Spring InvalidDataAccessApiUsageException - Spring InvalidDataAccessApiUsageException in async method using repository Spring-Data JPA:@Transactional 的 InvalidDataAccessApiUsageException - Spring-Data JPA: InvalidDataAccessApiUsageException for @Transactional
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM