Я занимаюсь разработкой веб-приложения для Spring и Hibernate, и я был настолько одержим тем, что сделал его потокобезопасным и смог поддерживать большую нагрузку, что на основе моей рекомендации босса я в итоге написал свой собственный сеанс и контейнер сеансов для реализовать сеанс для каждого шаблона запроса.
Вы должны просто отбросить весь этот код и использовать вместо него API-интерфейсы Spring / Hibernate: меньше ошибок, меньше обслуживания.
Я копирую и вставляю этот Hibernate GenericDAO (я не могу сказать, что это одно и то же, потому что в то время hibernate не принадлежал jboss) и делаю сантехнику, и под давлением все быстро усложняется (...)
Вы можете использовать GenericDao
и внедрять необходимые вещи с помощью Spring.
Вопрос 1 : достаточно ли безопасен сгенерированный Uiber Uuid для многопоточной среды и позволяет избежать StaleObjectException
?
Чтобы строго ответить на ваш вопрос, вот что Справочное руководство пишет о генераторе uuid:
...
Так что я считаю это безопасным. Но я думаю, что ваши StaleObjectException
не связаны (это другая проблема).
Вопрос 2 : как лучше всего использовать hibernate getCurrentSession в сценарии threadSafe (я читал о Threadlocal, но не слишком разбираюсь в этом, поэтому не сделал этого)
Лучшая стратегия состоит в том, чтобы просто использовать его, sessionFactory.getCurrentSession()
всегда даст вам Session
область действия для текущей транзакции базы данных, известную как «контекстный сеанс». Опять цитируем справочную документацию:
Большинство приложений, использующих Hibernate, необходимо
некоторая форма «контекстной» сессии,
где данный сеанс действует
во всем объеме данного
контекст. Тем не менее, через приложения
определение того, что составляет
контекст обычно отличается;
разные контексты определяют разные
выходит к понятию тока.
Приложения, использующие Hibernate до
версия 3.0, как правило, использует либо
самодельный ThreadLocal-based
контекстные сессии, вспомогательные классы
такой как HibernateUtil, или используется
сторонние фреймворки, такие как Spring
или Пико, который предоставил
контекст, основанный на прокси / перехвате
сессий.
(...)
Однако, начиная с версии 3.1,
обработка позади
SessionFactory.getCurrentSession()
теперь подключаем. С этой целью новый
интерфейс расширения,
org.hibernate.context.CurrentSessionContext
,
и новый параметр конфигурации,
hibernate.current_session_context_class
,
были добавлены, чтобы позволить подключаемость
объема и контекста определения
текущие сессии.
См. Javadocs для
org.hibernate.context.CurrentSessionContext
интерфейс для подробного обсуждения
его контракт. Определяет один
метод, currentSession()
, которым
реализация отвечает за
отслеживание текущего контекста
сессия. Готовый, Hibernate
поставляется с тремя реализациями
этот интерфейс:
org.hibernate.context.JTASessionContext
:
текущие сеансы отслеживаются и
ограничен транзакцией JTA.
обработка здесь точно такая же, как
в старом подходе только JTA. Увидеть
Javadocs для деталей.
org.hibernate.context.ThreadLocalSessionContext
:
текущие сессии отслеживаются потоком
исполнения. Смотрите Javadocs для
подробности.
org.hibernate.context.ManagedSessionContext
:
текущие сессии отслеживаются потоком
исполнения. Тем не менее, вы
ответственность связывать и отстегивать
Экземпляр сеанса со статическими методами
на этом классе: он не открывается,
очистить или закрыть сеанс.
(...)
В настоящее время нет необходимости внедрять собственное решение на основе ThreadLocal
, не делайте этого.
Вопрос 3 : подойдет ли HIbernateTemplate для простейшего подхода к решению?
Ну, HibernateTemplate
не рекомендуется, но больше не рекомендуется, и я предпочитаю внедрять DAO без шаблонов :
public class ProductDaoImpl implements ProductDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Collection loadProductsByCategory(String category) {
return this.sessionFactory.getCurrentSession()
.createQuery("from test.Product product where product.category=?")
.setParameter(0, category)
.list();
}
}
ГдеSessionFactory
вводится весной.Я предлагаю прочитать Так что вы все равно должны использовать Spring HibernateTemplate и / или JpaTemplate ?? для полного фона, а также весь раздел 13.3.Hibernate в документации Spring по доступу к данным ORM.
Вопрос 4: что вы выберете, если захотите реализовать пул соединений и требования к настройке для рабочего сервера?
Хм ... Что?Я бы никогда не реализовал свой пул соединений, но использовал бы его с моего сервера приложений.Возможно, вам следует уточнить этот вопрос.
Обновление: В работе я бы не использовал встроенный пул соединений Hibernate, а настроил бы Hibernate на использование источника данных JNDI сервера приложений (и, следовательно,пул соединений с сервером приложений).Из документации:
...
Вот пример hibernate.properties
файла для сервера приложений, предоставленного источником данных JNDI:
hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
Соединения JDBC, полученные из источника данных JNDI, будут автоматически участвовать в управляемых контейнером транзакциях сервера приложений.