Para cualquier persona que desee hacer esto en una sola línea (por ejemplo, en la/ventana Inmediato Display, una expresión de inspección o similar en una sesión de depuración), lo siguiente lo hará e "impresión bonita" el SQL:
new org.hibernate.jdbc.util.BasicFormatterImpl().format((new org.hibernate.loader.criteria.CriteriaJoinWalker((org.hibernate.persister.entity.OuterJoinLoadable)((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory().getEntityPersister(((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory().getImplementors(((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName())[0]),new org.hibernate.loader.criteria.CriteriaQueryTranslator(((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory(),((org.hibernate.impl.CriteriaImpl)crit),((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName(),org.hibernate.loader.criteria.CriteriaQueryTranslator.ROOT_SQL_ALIAS),((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory(),(org.hibernate.impl.CriteriaImpl)crit,((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName(),((org.hibernate.impl.CriteriaImpl)crit).getSession().getEnabledFilters())).getSQLString());
...o aquí está una versión más fácil de leer:
new org.hibernate.jdbc.util.BasicFormatterImpl().format(
(new org.hibernate.loader.criteria.CriteriaJoinWalker(
(org.hibernate.persister.entity.OuterJoinLoadable)
((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory().getEntityPersister(
((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory().getImplementors(
((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName())[0]),
new org.hibernate.loader.criteria.CriteriaQueryTranslator(
((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory(),
((org.hibernate.impl.CriteriaImpl)crit),
((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName(),
org.hibernate.loader.criteria.CriteriaQueryTranslator.ROOT_SQL_ALIAS),
((org.hibernate.impl.CriteriaImpl)crit).getSession().getFactory(),
(org.hibernate.impl.CriteriaImpl)crit,
((org.hibernate.impl.CriteriaImpl)crit).getEntityOrClassName(),
((org.hibernate.impl.CriteriaImpl)crit).getSession().getEnabledFilters()
)
).getSQLString()
);
Notas:
- La respuesta se basa en the solution posted by ramdane.i.
- Supone que el objeto Criteria se llama
crit
. Si recibe un nombre diferente, realice una búsqueda y reemplace.
- Asume que la versión de Hibernate es posterior a 3.3.2.GA pero anterior a la 4.0 para usar BasicFormatterImpl para "imprimir bastante" el HQL. Si usa una versión diferente, vea this answer para saber cómo modificar. O tal vez simplemente elimine por completo la bonita impresión, ya que es simplemente un "bueno tener".
- Se trata de utilizar
getEnabledFilters
en lugar de getLoadQueryInfluencers()
para la compatibilidad hacia atrás ya que este último se introdujo en una versión posterior de Hibernate (3,5 ???)
- no de salida los valores de parámetro real utilizado si la consulta es parametrizada.
¿No sería más portátil redirigir temporalmente el registro de hibernación a una cadena? –
Posiblemente, pero si varios subprocesos ejecutan SQL al mismo tiempo, puede ser difícil determinar qué mensajes de registro van con el SQL que está tratando de capturar. Un interceptor que usa onPrepareStatement también le daría el SQL, pero el OP pidió una forma de obtener el SQL para un objeto Criteria dado. –
¿Hay alguna forma de obtener también los parámetros de la consulta SQL impresos? – JRR