В настоящее время я работаю над (довольно большим) домашним проектом моего любимца, приложение Swing, которым он должен быть очень многопоточным. Почти все пользовательские взаимодействия могут извлекать данные с некоторых удаленных серверов через Интернет, поскольку я не контролирую эти серверы и сам Интернет, поэтому длительное время ответа неизбежно. Пользовательский интерфейс Swing явно не может перерисовываться, пока EDT занят, поэтому все удаленные серверные вызовы должны выполняться фоновыми потоками.
Моя проблема:
Данные, получаемые фоновыми потоками, становятся "обогащенными" данными из локальной (в памяти) базы данных (удаленный сервер возвращает идентификаторы/ссылки на данные в локальной базе данных). Эти данные позже передаются в EDT, где они становятся частью модели представления. В этот момент некоторые объекты не полностью инициализированы (включена ленивая выборка), поэтому пользователь может инициировать ленивую выборку, например. прокрутка в JTable. Поскольку сеанс hibernate уже закрыт, это вызовет исключение LazyInitializationException. Я не знаю, когда пользователь может вызвать ленивую выборку, поэтому создание сеанса по требованию/прикрепление отдельного объекта здесь не будет работать.
Я решил эту проблему:
- с использованием одного (синхронизированного, так как экземпляры сеанса не являются потокобезопасными) Сессия для всего приложения
- отключить ленивый выбор.
В то время как это работает, производительность приложения сильно пострадала (иногда близкая к непригодной для использования). Замедление в основном вызвано большим количеством объектов, которые теперь извлекаются каждым запросом.
В настоящее время я думаю об изменении дизайна приложения на "Session-per-thread" и переносе всех объектов, полученных из потоков, отличных от EDT, в сеанс потока EDT (аналогично это сообщение на форумах Hibernate).
Боковое примечание. Любые проблемы, связанные с обновлениями базы данных, не применяются, поскольку все объекты базы данных доступны только для чтения (справочные данные).
Любые другие идеи о том, как использовать Hibernate с ленивой загрузкой в этом сценарии?