Будьте в спящем режиме и сухо рабочие запросы HQL статически

Другой способ пойти (возможно, не самый быстрый) состоит в том, чтобы определить, является ли ln (x) / ln (2) целым числом.

5
задан Juha Syrjälä 11 February 2010 в 06:52
поделиться

2 ответа

The short answer is "you can't". The long answer is below.

There are two approaches you can take:

A) Look into HQLQueryPlan class, particularly its getSqlStrings() method. It will not get you the exact SQL because further preprocessing is involved before query is actually executed (parameters are bound, limit / offset are applied, etc...) but it may be close enough to what you want.

The thing to keep in mind here is that you'll need an actual SessionFactory instance in order to construct HQLQueryPlan, which means you won't be able to do so without "connecting to any database". You can, however, use in-memory database (SqlLite and the likes) and have Hibernate auto-create necessary schema for it.

B) Start with ASTQueryTranslatorFactory and descend into AST / ANTLR madness. In theory you may be able to hack together a parser that would work without relying on metadata but I have a hardest time imagining what is it you're trying to do for this to be worth it. Perhaps you can clarify? There has to be a better approach.

5
ответ дан 14 December 2019 в 08:52
поделиться

Обновление: для автономного пробного запуска некоторого HQL использование HQLQueryPlan напрямую является хорошим подходом . Если вы хотите перехватывать каждый запрос в приложении, пока оно выполняется, и записывать SQL, вам придется использовать прокси и отражение, как описано ниже.

Взгляните на этот ответ для критериев Запросы.

Для HQL это та же концепция - вы должны преобразовать классы реализации Hibernate и / или получить доступ к закрытым членам, поэтому это не поддерживаемый метод, но он будет работать с версиями Hibernate 3.2–3.3. Вот код для доступа к запросу из HQL (запрос - это объект, возвращаемый session.createQuery (hql_string):

Field f = AbstractQueryImpl.class.getDeclaredField("session");
f.setAccessible(true);
SessionImpl sessionImpl = (SessionImpl) f.get(query);
Method m = AbstractSessionImpl.class.getDeclaredMethod("getHQLQueryPlan", new Class[] { String.class, boolean.class });
m.setAccessible(true);
HQLQueryPlan plan = (HQLQueryPlan) m.invoke(sessionImpl, new Object[] { query.getQueryString(), Boolean.FALSE });
for (int i = 0; i < plan.getSqlStrings().length; ++i) {
  sql += plan.getSqlStrings()[i];
}

Я бы обернул все это в try / catch, чтобы вы могли продолжить запрос, если ведение журнала не не работает.

2
ответ дан 14 December 2019 в 08:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: