Hibernate: Разобрать / перевести часть HQL FROM, чтобы получить пары псевдоним класса, имя класса - PullRequest
3 голосов
/ 27 ноября 2008

Может ли кто-нибудь указать мне, как я могу проанализировать / оценить HQL и получить карту, где ключ - псевдоним таблицы, а значение - полное имя класса.

например. для HQL

ВЫБРАТЬ a.id из Foo ВНУТРЕННЕГО СОЕДИНЕНИЯ a.test b

Я хочу иметь пары:

a, package1.Foo

б. package2.TestClassName

Это относительно легко сделать для набора результатов

HQLQueryPlan hqlPlan = ((SessionFactoryImpl)sf).getQueryPlanCache().getHQLQueryPlan( getQueryString(), false, ((SessionImpl)session).getEnabledFilters() );
String[] aliases = hqlPlan.getReturnMetadata().getReturnAliases();
Type[] types = hqlPlan.getReturnMetadata().getReturnTypes();

См. подробности здесь .

Ответы [ 2 ]

4 голосов
/ 19 декабря 2008

Вряд ли это хороший способ сделать это, но кажется, что вы можете получить AST через некоторые внутренние интерфейсы и пройти через это:

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);

Так что, похоже, это извлекает сопоставления псевдонимов из скомпилированного запроса, но я бы очень осторожно использовал это решение: оно преобразует объекты в подклассы, обычно не видимые для hibernate-клиента, и интерпретирует AST на основе угадывания семантики разные узлы. Это может работать не для всех операторов HQL, и может не работать или иметь другое поведение в будущей версии hibernate.

0 голосов
/ 20 декабря 2008

Я нашел правильное решение для моего вопроса. Ваш оригинальный пост был почти верным, кроме этой части:

if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) {
 FromElement id = (FromElement)node;
 System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName());
}

Пожалуйста, исправьте свой ответ, и я принимаю его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...