Hibernate: Parse / Translate HQL FROM part para obtener pares alias de clase, nombre de clase
-
11-07-2019 - |
Pregunta
¿Alguien puede señalarme? ¿Cómo puedo analizar / evaluar HQL y obtener un mapa donde la clave es el alias y el valor de la tabla? Nombre de clase completo.
Por ejemplo. para HQL
SELECCIONE a.id de Foo a INNER JOIN a.test b
Deseo tener pares:
a, paquete1.Foo
b. package2.TestClassName
Es relativamente fácil de hacer para el conjunto de resultados
HQLQueryPlan hqlPlan = ((SessionFactoryImpl)sf).getQueryPlanCache().getHQLQueryPlan( getQueryString(), false, ((SessionImpl)session).getEnabledFilters() ); String[] aliases = hqlPlan.getReturnMetadata().getReturnAliases(); Type[] types = hqlPlan.getReturnMetadata().getReturnTypes();
Ver detalles aquí .
Solución
Difícilmente es una buena forma de hacerlo, pero parece que puede obtener el AST a través de algunas interfaces internas y atravesar esto:
QueryTranslator[] translators = hqlPlan.getTranslators();
AST ast = (AST)((QueryTranslatorImpl)translators[0]).getSqlAST();
new NodeTraverser(new NodeTraverser.VisitationStrategy() {
public void visit(AST node) {
if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) {
FromElement id = (FromElement)node;
System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName());
}
}
}).traverseDepthFirst(ast);
Por lo tanto, esto parece recuperar las asignaciones de alias de la consulta compilada, pero sería muy cuidadoso al usar esta solución: convierte objetos en subclases que generalmente no son visibles para un cliente de hibernación e interpreta el AST basándose en adivinar la semántica de Los diferentes nodos. Esto podría no funcionar en todas las declaraciones HQL, y podría no funcionar, o tener un comportamiento diferente, en una futura versión de hibernación.
Otros consejos
Encontré la solución correcta para mi pregunta. Su publicación original era casi correcta, excepto esa parte:
if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) {
FromElement id = (FromElement)node;
System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName());
}
Corrija su respuesta respuesta y la acepto.