#java #hibernate #jpa #entitymanager
#java #спящий режим #jpa #entitymanager
Вопрос:
Я пытаюсь запустить собственный запрос в цикле, запрос отображает правильный синтаксис sql, но результат всегда один и тот же.
for (int i=0; i<translations.size(); i ) {
Query query = entityManager.createNativeQuery("Select * from " translations.get(i).getName(), MyModel.class);
rows = (List<MyModel>)query.getResultList();
// rest of the function...
}
теперь в консоли я вижу операторы гибернации, такие как:
Hibernate: Select * from translation1
Hibernate: Select * from translation2
Hibernate: Select * from translation3
но переменная «rows» всегда содержит результат первого оператора select, т.е. Строки таблицы translation1.
Есть идеи, почему в консоли он показывает, что он также выбирает из других таблиц, но на самом деле он всегда получает данные из таблицы translation1?
Комментарии:
1. У вас одинаковые значения полей идентификаторов в этих таблицах?
2. на самом деле невозможно ответить на это, не видя везде, что
rows
используется. Например, почему неrows
объявлено в цикле for?3. @axtavt да, все таблицы имеют одинаковые идентификаторы и одинаковые имена столбцов, за исключением одного столбца, rowText, он содержит текст на разных языках в зависимости от таблицы преобразования.
Ответ №1:
Если все таблицы имеют одинаковый набор идентификаторов, это ожидаемое поведение.
Кэш сеанса гибернации гарантирует, что внутри сеанса может быть только один экземпляр объекта определенного типа с определенным идентификатором. Поскольку сущности разрешаются через кэш сеанса даже в случае собственного запроса, вы получаете те же экземпляры.
Итак, у вас есть несколько вариантов:
- переосмыслите схему вашей базы данных
- создайте объекты из результата запроса вручную
- принудительно очистите кэш сеанса, вызвав
clear()
илиdetach()
Комментарии:
1. спасибо за помощь, я не могу изменить схему БД, EntityManager.clear() исправил проблему.
2. @user908452: обратите внимание, что
clear()
удаляет все объекты из кэша сеанса, что может привести к неожиданным побочным эффектам, если некоторые из этих объектов были загружены другими методами. Возможно, было бы лучше использоватьdetach()
для явного удаления только только что загруженных объектов.
Ответ №2:
Вы уверены, что переменная rows на самом деле не содержит ПОСЛЕДНИЙ из ваших возвращенных результатов? как вы инициализируете строки и что вы делаете с переменной внутри цикла? Если вы хотите получить все результаты от всех запросов, вам нужно добавить каждый из них (внутри цикла) в переменную list / set, объявленную ПЕРЕД запуском цикла.
Или вы могли бы использовать какой-нибудь правильный SQL и сделать:
SELECT * FROM Table1 [JOIN/UNION] Table2 etc...
Комментарии:
1. Я уверен, что переменная rows НЕ содержит последних данных, я инициализировал ее вне цикла, но я попытался инициализировать ее и внутри цикла, и все равно это не сработало. Я перебираю ArrayList строк и добавляю его в Map Карты.