Hola,
En primer lugar, gracias por esta gran biblioteca.
El error que estoy experimentando es el siguiente:
Vincular una lista vacía
Ninguna fábrica de argumentos registrada para '[]' de tipo java.util.List
¿Puede proporcionar más contexto? ¿Qué SQL estás ejecutando? ¿Qué proveedor de base de datos?
Hola @qualidafial ,
Sql: select * from invoice where invoice.id IN :ids
Proveedor de base de datos: SQL Server 2017
Bien, eso tiene sentido ahora.
JDBC es un poco extraño cuando se trabaja con matrices: debe conocer el nombre del tipo de datos utilizado por el proveedor de la base de datos. Para ayudar a Jdbi a conectar los puntos, debe registrar el nombre del tipo de elemento de matriz por nombre de clase de Java:
Jdbi jdbi = Jdbi.create(...);
...
jdbi.registerArrayType(int.class, "integer");
jdbi.registerArrayType(Integer.class, "integer");
Dicho esto, podríamos mejorar nuestros mensajes de excepción para señalar a los usuarios en la dirección correcta.
@qualidafial Bro, esto es de primera categoría, ¡muchas gracias!
: +1: Solo un aviso, podríamos agregar un complemento de SQL Server a Jdbi si puede indicarme algo de documentación para saber qué tipos de datos personalizados admite el controlador y cuáles son las asignaciones entre los tipos de Java y el tipo de datos JDBC nombres.
Trato.
Tipos de datos básicos:
https://docs.microsoft.com/en-us/sql/connect/jdbc/using-basic-data-types
Tipos de datos avanzados:
https://docs.microsoft.com/en-us/sql/connect/jdbc/using-advanced-data-types
@qualidafial FYI, aparentemente la instrucción IN con un SqlArray preparado no es compatible con el controlador JDBC de SQL Server
Alternativamente, podría usar @BindList
:
@SqlQuery("select * from invoice where invoice.id IN (<ids>)")
Set<Invoice> getInvoices(@BindList("ids") List<Integer> ids);
Tenga en cuenta que diferentes proveedores de bases de datos pueden poner límites al número de elementos permitidos en una cláusula WHERE column IN (a, b, c, ...)
separados por comas.
Aparentemente, el servidor SQL solo admite parámetros de valor único, por lo que creé la matriz manualmente, sin embargo, esto no es seguro para las matrices de cadenas y puede introducir la inyección SQL.
default List<LotInvoiceRef> getInvoices(List<Long> invoiceIds) {
final List<LotInvoiceRef> lotInvoiceRefs = invoiceIds.stream()
.map(String::valueOf)
.reduce((a, b) -> a + "," + b)
.map(this::getAllInvoiceRefs)
.orElse(new ArrayList<>());
return lotInvoiceRefs;
}
@georgerb , consulte mi último comentario, que debería proteger contra la inyección de SQL
@qualidafial Me encanta el enfoque @BindList pero necesito una forma de permitir listas vacías para el parámetro que @BindList prohíbe explícitamente.
@qualidafial nvm, una @BindList(value = "invoiceIds", onEmpty = BindList.EmptyHandling.NULL)
y funcionó perfectamente
Una vez más, esto es de primera categoría. ¿Hay alguna forma en que podamos contribuir? al menos ayudándolos con la documentación.
Gracias, eres muy amable. Nosotros: corazón: ¡solicitudes de extracción!
Solo de esta conversación, obtengo tres posibles mejoras:
@BindList
(y tal vez @DefineList
mientras estamos en eso).Si tiene la amabilidad de enviar un problema por separado dirigido a cada uno de los anteriores. Luego podemos cerrar este y rastrear cada uno de forma aislada.
Y si tiene alguna idea para mejorar Jdbi con la que le gustaría ejecutar, ¡hágalo! Los complementos JPA, Kotlin y Vavr, así como muchos elementos de Core y SQL Object fueron todos envíos de usuarios de Jdbi.
@qualidafial hecho. # 993
¡Gracias! Cerrando este problema a favor del # 993
Comentario más útil
Bien, eso tiene sentido ahora.
JDBC es un poco extraño cuando se trabaja con matrices: debe conocer el nombre del tipo de datos utilizado por el proveedor de la base de datos. Para ayudar a Jdbi a conectar los puntos, debe registrar el nombre del tipo de elemento de matriz por nombre de clase de Java: