Reputation: 11
I'm trying to call to a PL/SQL stored procedure from MyBatis.
I'd try several options and configurations for the Select Callable statement type, but I'm block on this error.
I have this configurations / files:
The PL/SQL Method:
PROCEDURE re_pr_ins_apunte_ref ( p_seqrec IN RE_T_GE_RECEPTIVO.seq_rec%TYPE,
p_seqres IN NUMBER,
p_importe IN NUMBER,
p_divisa IN gn_t_divisa.cod_divisa%TYPE,
p_codref IN RE_T_AD_LIBRO_AGENCIA.cod_referencia_pago%TYPE,
p_codest IN RE_T_CD_ESTADO_COBRO.cod_estado%TYPE,
p_codpas IN RE_T_CD_ESTADO_COBRO.cod_pasarela%TYPE,
po_ok OUT BOOLEAN,
po_error OUT VARCHAR2,
p_autonomous IN BOOLEAN := TRUE, p_merchant_id IN RE_T_AD_LIBRO_AGENCIA.merchant_id%TYPE DEFAULT NULL
) IS
XML MyBatis Repository select operation:
<select id="agencyBookPostingLineInsRefCall"
parameterType="com.hotelbeds.commonbookingservice.entity.confirmation.agencybookpostingline.AgencyBookPostingLineInsIOWrapper"
statementType="CALLABLE">
{call Re_Pk_Libro_Agencia.re_pr_ins_apunte_ref(
#{wrapper.incomingOfficeId, mode=IN, jdbcType=INTEGER} => P_SEQREC
, #{wrapper.bookingNumber, mode=IN, jdbcType=INTEGER} => P_SEQRES
, #{wrapper.amount, mode=IN, jdbcType=NUMERIC} => P_IMPORTE
, #{wrapper.currencyId, mode=IN, jdbcType=VARCHAR} => P_DIVISA
, #{wrapper.referenceCode, mode=IN, jdbcType=VARCHAR} => P_CODREF
, #{wrapper.paymentStatus, mode=IN, jdbcType=VARCHAR} => P_CODEST
, #{wrapper.paymentGatewayId, mode=IN, jdbcType=VARCHAR} => P_CODPAS
, #{wrapper.ok, mode=OUT, jdbcType=VARCHAR, typeHandler=com.hotelbeds.commonbookingservice.db.handler.BooleanTrueFalseTypeHandler}
=> PO_OK
, #{wrapper.error, mode=OUT, jdbcType=VARCHAR }
=> PO_ERROR
, #{wrapper.autonomous, mode=IN, jdbcType=VARCHAR, typeHandler=com.hotelbeds.commonbookingservice.db.handler.BooleanTrueFalseTypeHandler}
=> P_AUTONOMOUS
, #{wrapper.merchantId, mode=IN, jdbcType=VARCHAR} => P_MERCHANT_ID
)
}
</select>
Method in interface class
[...]
void agencyBookPostingLineInsRefCall(@Param("wrapper") AgencyBookPostingLineInsIOWrapper wrapper);
[...]
The Wrapper Class for parameters:
/**
* Wrapper for the method AgencyBookPostingLineIns
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
public class AgencyBookPostingLineInsIOWrapper implements Serializable {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = -6621442227563572393L;
/** Input */
private Integer incomingOfficeId;
private Integer bookingNumber;
private BigDecimal amount;
private String currencyId;
private String referenceCode;
private String paymentStatus;
private String paymentGatewayId;
private Boolean autonomous;
private String merchantId;
/** Output */
private Boolean ok;
private String error;
Boolean Type Handler:
/**
* Example with values true,false to boolean Handler.
*/
@MappedTypes(Boolean.class)
public class BooleanTrueFalseTypeHandler extends AbstractBooleanTypeHandler {
/** The Constant FALSE_STRING. */
private static final String FALSE_STRING = "false";
/** The Constant TRUE_STRING. */
private static final String TRUE_STRING = "true";
/**
* The constructor
*/
public BooleanTrueFalseTypeHandler() {
super();
falseString = FALSE_STRING;
trueString = TRUE_STRING;
}
}
And The error:
==> Preparing: {call Re_Pk_Libro_Agencia.re_pr_ins_apunte_ref( ? => P_SEQREC , ? => P_SEQRES , ? => P_IMPORTE , ? => P_DIVISA , ? => P_CODREF , ? => P_CODEST , ? => P_CODPAS , ? => PO_OK , ? => PO_ERROR , ? => P_AUTONOMOUS , ? => P_MERCHANT_ID ) }
==> Parameters: 1(Integer), 3527758(Integer), 200(BigDecimal), EUR(String), 051609100(String), T(String), BIB(String), true(String), MERCHAN(String)
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: java.sql.SQLException: ORA-06550: línea 1, columna 7:
PLS-00306: wrong number or types of arguments in call to 'RE_PK_LIBRO_AGENCIA.RE_PR_INS_APUNTE_REF(P_SEQREC, P_SEQRES, P_IMPORTE, P_DIVISA, P_CODREF, P_CODEST, P_CODPAS, PO_OK, PO_ERROR, P_AUTONOMOUS, P_MERCHANT_ID)'
ORA-06550: línea 1, columna 7:
PL/SQL: Statement ignored
### The error may exist in com/hotelbeds/commonbookingservice/db/repository/booking/BookingReconfirmationRepository.xml
### The error may involve com.hotelbeds.commonbookingservice.db.repository.booking.BookingReconfirmationRepository.agencyBookPostingLineInsRefCall-Inline
### The error occurred while setting parameters
### SQL: {call Re_Pk_Libro_Agencia.re_pr_ins_apunte_ref( ? => P_SEQREC , ? => P_SEQRES , ? => P_IMPORTE , ? => P_DIVISA , ? => P_CODREF , ? => P_CODEST , ? => P_CODPAS , ? => PO_OK , ? => PO_ERROR , ? => P_AUTONOMOUS , ? => P_MERCHANT_ID ) }
### Cause: java.sql.SQLException: ORA-06550: línea 1, columna 7:
PLS-00306: wrong number or types of arguments in call to 'RE_PK_LIBRO_AGENCIA.RE_PR_INS_APUNTE_REF(P_SEQREC, P_SEQRES, P_IMPORTE, P_DIVISA, P_CODREF, P_CODEST, P_CODPAS, PO_OK, PO_ERROR, P_AUTONOMOUS, P_MERCHANT_ID)'
ORA-06550: línea 1, columna 7:
PL/SQL: Statement ignored
; bad SQL grammar []; nested exception is java.sql.SQLException: ORA-06550: línea 1, columna 7:
PLS-00306: wrong number or types of arguments in call to 'RE_PK_LIBRO_AGENCIA.RE_PR_INS_APUNTE_REF(P_SEQREC, P_SEQRES, P_IMPORTE, P_DIVISA, P_CODREF, P_CODEST, P_CODPAS, PO_OK, PO_ERROR, P_AUTONOMOUS, P_MERCHANT_ID)'
ORA-06550: línea 1, columna 7:
PL/SQL: Statement ignored
I thing the problem is related with the 2 OUT parameters.
Upvotes: 0
Views: 1667
Reputation: 11
The problem is suppoused to be because of the stored procedure BOOLEAN out parameter:
There is a known problem with PL/SQL BOOLEANS in ORACLE Jdbc.
http://docs.oracle.com/cd/A87861_01/NT817EE/java.817/a83723/typesup1.htm
Wrapping PL/SQL BOOLEAN, RECORD, and TABLE Types
Oracle JDBC drivers do not support calling arguments or return values of the PL/SQL types TABLE (now known as indexed-by tables), RECORD, or BOOLEAN.
As a workaround, you can create wrapper procedures that handle the data as types supported by JDBC. For example, to wrap a stored procedure that uses PL/SQL booleans, you can create a stored procedure that takes a character or number from JDBC and passes it to the original procedure as BOOLEAN, or, for an output parameter, accepts a BOOLEAN argument from the original procedure and passes it as a CHAR or NUMBER to JDBC. Similarly, to wrap a stored procedure that uses PL/SQL records, you can create a stored procedure that handles a record in its individual components (such as CHAR and NUMBER). To wrap a stored procedure that uses PL/SQL tables, you can break the data into components or perhaps use Oracle collection types.
I've had to implement a PL/SQL wrapper procedure that check de BOOLEAN value and which returns a VARCHAR to Java with jdbc connector.
PROCEDURE re_pr_ins_apunte_ref_w ( p_seqrec IN RE_T_GE_RECEPTIVO.seq_rec%TYPE, -- Oficina que gestiona el apunte
p_seqres IN NUMBER, -- Reserva
p_importe IN NUMBER, -- Importe Haber.
p_divisa IN gn_t_divisa.cod_divisa%TYPE,
p_codref IN RE_T_AD_LIBRO_AGENCIA.cod_referencia_pago%TYPE, -- Referencia de pago.
p_codest IN RE_T_CD_ESTADO_COBRO.cod_estado%TYPE,
p_codpas IN RE_T_CD_ESTADO_COBRO.cod_pasarela%TYPE,
po_ok OUT VARCHAR2, -- Indica si la funcion ha terminado correctamente
po_error OUT VARCHAR2,
p_autonomous IN BOOLEAN := TRUE, -- True: Nextval, False: Nextval_no_autonomous
p_merchant_id IN RE_T_AD_LIBRO_AGENCIA.merchant_id%TYPE DEFAULT NULL
) IS
vo_ok BOOLEAN;
BEGIN
re_pr_ins_apunte_ref( p_seqrec, -- Oficina que gestiona el apunte
p_seqres, -- Secuencia de la venta (seq_reserva, seq_cargo, seq_expediente, seq_contr)
p_importe, -- Importe Haber.
p_DIVISA, -- Divisa en la que está expresado el importe
p_codref, -- Referencia de pago.
p_codest,
p_codpas,
vo_ok, -- Indica si la funcion ha terminado correctamente
po_error, -- Descripcion del error
p_autonomous, -- True: Nextval, False: Nextval_no_autonomous
p_merchant_id);
IF (VO_OK) THEN
po_ok := 'S';
ELSE
po_ok := 'N';
END IF;
END re_pr_ins_apunte_ref_w;
Upvotes: 1