El comodín para hablarle a la base en su propio idioma. Dale play y lo entendés de una vez.
Hablás de campos Java: i.authCode, el atributo de la entidad.
La base habla de columnas reales: auth_code en la tabla.
Vos escribís JPQL. Hibernate lo traduce a SQL antes de mandarlo a la base. Nunca ves el SQL — el traductor lo arma solo.
JPQL es agnóstico de base: no lo atás a ninguna. Esa portabilidad es su superpoder.
El costo: para ser portable, solo conoce un diccionario chico de funciones — las que existen en todas las bases:
Es una función de MariaDB para buscar con expresiones regulares. Potente, pero específica de esa base.
El traductor no la tiene en su diccionario → no la sabe decir → no la podés escribir en JPQL normal. Punto muerto.
En criollo: le decís al traductor "che, esta palabra pasala tal cual, no la traduzcas".
El campo authCode se tradujo a auth_code. La función regexp_instr pasó intacta. Eso hace function().
La posición donde matchea el patrón (1, 2, 3…) o 0 si no matchea.
Por eso el filtro dice = 0: "no matchea el patrón de marca → conservá la fila".
Si la función no está registrada en el dialect (nuestro caso), Hibernate 5 la reenvía confiando en que la base la tenga. No la valida, no la chequea — solo la deja pasar.
La función tiene que existir en esa base. Perdés la portabilidad que era la gracia de JPQL.
Hibernate no valida los argumentos ni el retorno. Si te equivocás, revienta en runtime.
En un repo donde nunca se usó, salta a la vista aunque sea JPA estándar. Documentalo.
No es un hack ni un native query: es API oficial de JPA. Pero se paga con portabilidad y con que hay que explicarlo.
Meter una función de la base adentro de un query JPQL, sin salir a native ni tocar el dialect.