Как я могу настроить hibernate на использование информации о подключении, зависящей от контекста? - PullRequest
1 голос
/ 24 апреля 2009

Я пишу приложение Java SE (примечание, , а не Java EE) с использованием Hibernate, и мне нужно предоставить отдельное соединение с Hibernate для каждого потока выполнения. Эти соединения должны быть объединены, и каждое из них имеет как минимум различную аутентификацию и, возможно, свой URL JDBC. Соединения будут использоваться повторно (что может быть выведено из требования объединения).

Какие части Hibernate / C3P0 / et al я должен переопределить? Можно ли это сделать с помощью этих инструментов или мне нужно написать собственный источник данных пула?

Ответы [ 2 ]

1 голос
/ 24 апреля 2009

Я думаю, что лучшим способом было бы создать SessionFactory для каждого источника данных с возможно объединенными соединениями - это то, что eqbridges предложило в его ответе.

Теперь Hibernate имеет хук ConnectionProvider, поэтому я полагаю, что вы могли бы написать реализацию, которая возвращала бы Connection s в разные источники данных, в зависимости от текущего потока выполнения и некоторых дополнительных параметров. Теоретически, вы можете иметь один экземпляр SessionFactory, который будет использовать разные соединения с разными базами данных, предоставленные вашей пользовательской реализацией ConnectionProvider. Но один SessionFactory содержит довольно много данных, и эти данные затем используются Hibernate для внутреннего использования при открытии Session для единицы работы. Кроме того, с ним также связан кэш второго уровня.

К сожалению, как фабрика и Session s, которые вы открываете из нее, будут вести себя перед лицом такого провайдера, никто не догадывается. Для меня это похоже на хак, и я сомневаюсь, что это когда-либо считалось жизнеспособным вариантом использования для SessionFactory. Это может привести к всевозможным, возможно очень незначительным, ошибкам или повреждению данных.

С другой стороны, обязательно точно измерьте стоимость создания нескольких SessionFactories - она ​​может быть не такой высокой, как вы думаете. Обязательно сравните это со стоимостью простого открытия необходимых соединений JDBC. Я не знаю, какие результаты вы можете получить, но я думаю, что вы должны быть уверены в производительности, прежде чем прибегнуть к более хакерским решениям.

1 голос
/ 24 апреля 2009

У вас есть два вопроса здесь:

  1. Соединения не являются потокобезопасными, поэтому каждый поток должен иметь свое собственное соединение. Поскольку вы работаете с Hibernate, то, что видит ваше приложение, на самом деле является Session, полученным из SessionFactory. Чтобы использовать это, вы вызываете метод SessionFactory # getCurrentSession () и конфигурируете текущий контекст сеанса в hibernate.cfg.xml:
    <property name="current\_session\_context\_class">thread</property>
    Если вы правильно настроили пул потоков (используя c3po или любой другой механизм пулирования, который вы предпочитаете) в hibernate.cfg.xml, то каждый поток получит соединение из этого пула.
  2. Чтобы поддерживать несколько источников данных, с которыми приложению может потребоваться работать, необходимо настроить отдельную SessionFactory для каждого URL-адреса JDBC, к которому вы хотите получить доступ. В вашем приложении вам понадобятся некоторые средства выбора с помощью SessionFactory, которые вам нужно будет выбрать (например, «идентификатор клиента»), с помощью которых вы можете управлять каждым из экземпляров SessionFactory в карте или некоторой такой структуре данных (в Java). EE приложение, которое вы получите от JNDI).

Подводя итог (и обобщая), в сущности, SessionFactory - это, по сути, огромная оболочка вокруг источника данных (и пула соединений оператора). Это только для чтения (и, следовательно, потокобезопасный), тяжеловесный и статический, сконструированный один раз, и он знает все, что нужно о данном источнике данных.

Сеанс, с другой стороны, по сути является облегченной оболочкой вокруг Соединения. Он не безопасен для нитей, часто недолговечен и предназначен для использования, а затем выбрасывается.

Надеюсь, это поможет!

...