No momento, estou tentando implementar um construtor de consulta genérico que pode ser reutilizado em diferentes entidades. Estou usando o Blaze Persistence para montar a consulta. Uma das opções que o construtor deve suportar é verificar se um atributo List contém um determinado valor. Então, em pseudocódigo, isso significaria Entity.Attribute.contains(passedValue). O que estou lutando agora é fazer essa consulta funcionar. Criei uma visualização que contém o seguinte campo
@Type(ListArrayType.class)
@Column(name = "co_creators", columnDefinition = "UUID[]")
private List<UUID> coCreators;
que é criado assim
COALESCE(
(SELECT ARRAY_AGG(cc.cocreatorid)
FROM cocreator cc
WHERE cc.elementid = c.id
AND cc.elementtype = 'COURSE'),
'{}'
) AS co_creators
Em seguida, tento montar a consulta das seguintes maneiras, porém nada funciona como esperado:
- onde(valor).em(campoNome)
restrictionBuilder = criteria.where(queryParams.getValue().toString());
restrictionBuilder.in(queryParams.getFieldName());
Isso resultará em
com.blazebit.persistence.parser.expression.SyntaxErrorException: Could not parse expression '7035bf82-a831-4a78-8615-6cc0e0c1ca26', line 1:4 mismatched input 'bf82' expecting {<EOF>, '+', '-', '*', '/', '%', '||'}
- Definir valor como um parâmetro
restrictionBuilder = criteria.where(":value");
restrictionBuilder.in(queryParams.getFieldName());
criteria.setParameter("value", queryParams.getValue().toString());
Isso criará uma consulta como:
SELECT selectedObject FROM CourseView selectedObject WHERE :value IN (:param_0) ORDER BY selectedObject.uuid DESC
No entanto, isso parece estar correto se eu tiver uma Entidade com o campo coCreators como:
{7035bf82-a831-4a78-8615-6cc0e0c1ca26}
E passe '7035bf82-a831-4a78-8615-6cc0e0c1ca26'
como meu valor, ele retornará uma lista vazia, mas espero que a entrada acima seja encontrada.
- Usar FUNÇÃO
Eu também tentei
restrictionBuilder = criteria.where("FUNCTION('any', :value, coCreators)");
criteria.setParameter("value", queryParams.getValue().toString());
no entanto isso resulta emResolved [java.lang.IllegalArgumentException: Parameter name "value" does not exist]
- Use FUNCTION sem parâmetros
Então eu tentei o mesmo sem setParameter
, tipo
restrictionBuilder =
criteria.where("FUNCTION('any', " + queryParams.getValue().toString() + ", coCreators)");
criteria.setParameter("value", queryParams.getValue().toString());
O que vai acabar sendo o mesmo SyntaxErrorException
que minha primeira opção
- Valor de escape
Também escapando do valor como
restrictionBuilder = criteria.where("FUNCTION('any', '" + queryParams.getValue().toString() + "', coCreators)");
não ajuda. Isso vai acabar com
ExceptionHandlerExceptionResolver : Resolved [com.blazebit.persistence.impl.BuilderChainingException: A builder was not ended properly.]
- Valor de escape com
eq(true)
Então eu tentei isso
restrictionBuilder =
criteria.where("FUNCTION('any', '" + queryParams.getValue().toString() + "', coCreators)");
restrictionBuilder.eq(true);
como qualquer deve retornar um booleano, no entanto isso também não resolve o problema, pois resulta em:
Caused by: org.postgresql.util.PSQLException: ERROR: invalid input syntax for type boolean: "7035bf82-a831-4a78-8615-6cc0e0c1ca26"
Position: 562
Estou completamente perdido aqui e realmente apreciaria alguma ajuda. Existe alguma maneira de fazer isso funcionar do jeito que preciso usando Blaze Persistence?
Acho que uma opção seria usar uma consulta nativa, no entanto, deve ser possível usar apenas uma consulta nativa para essa condição, mas combiná-la com outras condições (não nativas). No entanto, também não sei como incluir consultas/condições personalizadas no Blaze Persistence.