Hibernate: Parse / Translate HQL FROM part para obtener pares alias de clase, nombre de clase

StackOverflow https://stackoverflow.com/questions/324105

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í .

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top