2008-09-23 9 views
8

On m'a demandé de prendre en charge plusieurs bases de données dans la même instance, afin de prendre en charge l'hébergement multiclient. Chaque base de données a un schéma identique. L'utilisateur se connecte à une base de données spécifique en choisissant parmi une liste, et tous les appels suivants iront à cette base de données jusqu'à ce qu'ils se déconnectent.Plusieurs fabriques de sessions sous Spring/Hibernate

Je souhaite remplacer à chaud la fabrique de sessions dans un seul HibernateDaoTemplate basé sur un paramètre fourni par le client.

Je peux trouver beaucoup de choses sur les sources de données échangeables à chaud (et tous les problèmes de transaction associés), mais je veux remplacer les usines de session - conservant toute la mise en cache pour chacune.

Quelle est la manière la plus facile de faire cela? Configurer un HotSwappableTarget pour le DaoTemplate? Quelqu'un peut-il me montrer des exemples sur la façon de faire cela?

Répondre

2

Si toutes les bases de données sont identiques, je peux suggérer d'utiliser une seule SessionFactory et de fournir vos propres implémentations pour le DataSource et le Cache qui sont réellement «tenant compte». (La mise en œuvre de ceux-ci est assez triviale: il suffit de maintenir une carte de l'ID du locataire -> cache réel/source de données réelle, puis de déléguer tous les appels à l'approprié). Configurez l'unique SessionFactory pour utiliser votre Cache et DataSource compatibles avec le locataire. Un ThreadLocal peut être utilisé pour rendre l'ID du locataire de la requête en cours disponible pour tout code qui doit en être informé.

J'ai utilisé cette approche avant de réussir à prendre en charge le multiclient.

+0

Bonne idée - mais comment basculer dans le cache prenant en charge les locataires? Tout ce que vous pouvez faire est de configurer un fournisseur de cache, et Hibernate l'utilise sous les couvertures pour créer un cache. Peut-être implémenter un CacheProvider qui à son tour génère un wrapper de cache prenant en charge les locataires? – Verdant

0

Vous pouvez aussi jeter un oeil sur le projet Hibernate Shards:

http://www.hibernate.org/414.html

... qui se concentre sur l'ajout du support pour le partitionnement horizontal au Hibernate Core. Il ne couvre pas encore l'API Hibernate complète, mais en supporte une grande partie (ce qui peut être suffisant ou non pour vos besoins). Bien sûr, ils travaillent vers une couverture complète.

2

Où je travaillais nous avons fait ceci via ThreadLocal suivant this guide. Nous avons juste utilisé un SessionFactory et changé sa source de données basée sur une variable de session que l'utilisateur pourrait changer en étant connecté. Je ne me souviens pas des détails exacts, mais si vous Je suis intéressé, je peux trouver plus d'informations sur notre implémentation. Cela dit, les gars de mon ancien lieu de travail s'éloignent maintenant de cette approche et se dirigent vers une base de données partagée. Certainement une solution plus élégante que je vous recommande de regarder.

1

étendre votre classe DAO à partir HibernateDaoSupport, puis invoquer la méthode setSessionFactory(), pour faire le remplacement à chaud des bases de données

0

J'ai aussi essayé le fournisseur de cache via ThreadLocal et la partie difficile faisait le remplacement à chaud sur le cache , vous devez vous assurer que SessionFactory n'a aucune session active associée. Maintenant, je pense qu'il y a une bien meilleure solution: en utilisant la configuration java Spring 3, vous pouvez créer dynamiquement votre SessionFactory tenant compte du locataire et laisser Spring faire la gestion du cache pour vous.