Как наилучшим образом отображать результаты SQL-запроса на объект объекта без объекта с использованием Hibernate? - программирование
Подтвердить что ты не робот

Как наилучшим образом отображать результаты SQL-запроса на объект объекта без объекта с использованием Hibernate?

У меня есть управляемый Java-объект Hibernate под названием X и встроенная функция SQL (myfunc), которую я вызываю из запроса Hibernate SQL по этим строкам:

SQLQuery q = hibernateSession.createSQLQuery(
                     "SELECT *, myfunc(:param) as result from X_table_name"
             );

То, что я хочу сделать, - это сопоставить все, что было возвращено из этого запроса, в класс (не обязательно управляемый Hibernate), который называется Y. Y должен содержать все свойства/поля из X плюс result, возвращаемые myfunc, например Y может расширить класс X и добавить поле "результат".

Что я пробовал:

  • Я пробовал использовать q.addEntity(Y.class), но это не удалось: org.hibernate.MappingException: Unknown entity com.mycompany.Y
  • q.setResultTransformer(Transformers.aliasToBean(Y.class));, но это не удается: org.hibernate.PropertyNotFoundException: Could not find setter for some_property. X имеет поле под названием someProperty с соответствующим получателем и установщиком, но в этом случае не похоже, что Hibernate сопоставляет имя столбца (some_property) правильному имени поля.
  • q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); возвращает карту, но значения не всегда относятся к типу, ожидаемому соответствующим полем в X. Например, поля в X типа enum и Date не могут быть сопоставлены непосредственно из Map, возвращаемого SQL-запросом (где это строки).

Каким образом можно справиться с этой ситуацией?

4b9b3361

Ответ 1

См. главу документации о SQL-запросах.

Вы можете использовать метод addScalar(), чтобы указать, какой тип Hibernat должен использовать для данного столбца.

И вы можете использовать псевдонимы для сопоставления результатов с помощью свойств bean:

select t.some_property as someProperty, ..., myfunc(:param) as result from X_table_name t

Или, (и хотя для этого требуются некоторые строки кода, это мое предпочтительное решение), вы можете просто сделать отображение самостоятельно:

List<Object[]> rows = query.list();
for (Object[] row : rows) {
    Foo foo = new Foo((Long) row[0], (String) row[1], ...);
}

Это позволяет избежать отражения и позволяет вам контролировать все.

Ответ 2

Легко

final org.hibernate.Query q = session.createSQLQuery(sql);
q.setParameter("geo",geo);
q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
final List<Map<String,Object>> src = q.list();
final List<VideoEntry> results = new ArrayList<VideoEntry>(src.size());
for (final Map<String,Object> map:src) {
final VideoEntry entry = new VideoEntry();
BeanUtils.populate(entry,map);
results.add(entry);
}

Ответ 3

Прежде всего вам нужно объявить сущность в файле конфигурации xibernate конфигурации примерно так:..... class= "путь к вашей сущности"

Или вы можете сделать то же самое программно, прежде чем делать запрос.