Hibernate.orgCommunity Documentation

Chapitre 28. Considérations de portabilité des bases de données

28.1. Aspects fondamentaux de la portabilité
28.2. Dialecte
28.3. Résolution de dialecte
28.4. Générer les identifiants
28.5. Fonctions de base de données
28.6. Type mappings

La portabilité des bases de données est un des atouts qui sont mis en avant pour vendre Hibernate (et plus largement le mappage objet/relationnel dans son ensemble). Il pourrait s'agir d'un utilisateur IT interne qui migre d'une base de données de fournisseur vers une autre, ou il pourrait s'agir d'un framework ou d'une application déployable consommant Hibernate pour cibler simultanément plusieurs produits de base de données par leurs utilisateurs. Quel que soit le scénario exact, l'idée de base est que vous souhaitez que HIBERNATE vous permettre d'exécuter avec un certain nombre de bases de données sans modifications à votre code et idéalement sans modifications des métadonnées de mappage.

La première ligne de la portabilité d'Hibernate est le dialecte, qui est une spécialisation du contrat org.Hibernate.dialect.dialect. Un dialecte encapsule toutes les différences selon lesquelles Hibernate doit communiquer avec une base de données particulière pour accomplir certaines tâches comme l'obtention d'une valeur de la séquence ou de structuration d'une requête SELECT. Hibernate regroupe un large éventail de dialectes pour la plupart des bases de données les plus communes. Si vous trouvez que votre base de données particulière n'en fait pas partie, il n'est pas difficile d'écrire votre propre dialecte.

À l'origine, Hibernate exigeait toujours que les utilisateurs spécifient quel dialecte utiliser. Dans le cas des utilisateurs qui cherchent à cibler simultanément plusieurs bases de données avec leur version, c'était problématique. Généralement cela amenait leurs utilisateurs à configurer le dialecte Hibernate ou à définir leur propre méthode de définition de cette valeur.

A partir de la version 3.2, Hibernate a introduit la détection automatiquement du dialecte à utiliser basé sur les Java.SQL.DatabaseMetaData obtenues à partir d'un Java.SQL.Connexion vers cette base de données. C'était beaucoup mieux, sauf que cette résolution a été limitée aux bases de données déjà connues d'Hibernate et elle n'était ni configurable, ni remplaçable.

Starting with version 3.3, Hibernate has a fare more powerful way to automatically determine which dialect to should be used by relying on a series of delegates which implement the org.hibernate.dialect.resolver.DialectResolver which defines only a single method:

public Dialect resolveDialect(DatabaseMetaData metaData) throws JDBCConnectionException

The basic contract here is that if the resolver 'understands' the given database metadata then it returns the corresponding Dialect; if not it returns null and the process continues to the next resolver. The signature also identifies org.hibernate.exception.JDBCConnectionException as possibly being thrown. A JDBCConnectionException here is interpreted to imply a "non transient" (aka non-recoverable) connection problem and is used to indicate an immediate stop to resolution attempts. All other exceptions result in a warning and continuing on to the next resolver.

Le bon côté de ces outils de résolution, c'est que les utilisateurs peuvent également enregistrer leurs propres outils de résolution personnalisés, qui seront traités avant les résolveurs Hibernate intégrés. Cette option peut être utile dans un certain nombre de situations différentes : elle permet une intégration aisée pour la détection automatique des dialectes au-delà de ceux qui sont livrés avec Hibernate lui-même ; elle vous permet de spécifier d'utiliser un dialecte personnalisé lorsqu'une base de données particulière est reconnue ; etc.. Pour enregistrer un ou plusieurs outils de résolution, il vous suffit de les spécifier (séparés par des virgules, des onglets ou des espaces) à l'aide du paramètre de configuration 'hibernate.dialect_resolvers' (voir la constante DIALECT_RESOLVERS sur cfg.Environment org.Hibernate.).

When considering portability between databases, another important decision is selecting the identifier generation stratagy you want to use. Originally Hibernate provided the native generator for this purpose, which was intended to select between a sequence, identity, or table strategy depending on the capability of the underlying database. However, an insidious implication of this approach comes about when targtetting some databases which support identity generation and some which do not. identity generation relies on the SQL definition of an IDENTITY (or auto-increment) column to manage the identifier value; it is what is known as a post-insert generation strategy becauase the insert must actually happen before we can know the identifier value. Because Hibernate relies on this identifier value to uniquely reference entities within a persistence context it must then issue the insert immediately when the users requests the entitiy be associated with the session (like via save() e.g.) regardless of current transactional semantics.

The underlying issue is that the actual semanctics of the application itself changes in these cases.

Starting with version 3.2.3, Hibernate comes with a set of enhanced identifier generators targetting portability in a much different way.

Note

There are specifically 2 bundled enhancedgenerators:

  • org.hibernate.id.enhanced.SequenceStyleGenerator

  • org.hibernate.id.enhanced.TableGenerator

The idea behind these generators is to port the actual semantics of the identifer value generation to the different databases. For example, the org.hibernate.id.enhanced.SequenceStyleGenerator mimics the behavior of a sequence on databases which do not support sequences by using a table.

SQL functions can be referenced in many ways by users. However, not all databases support the same set of functions. Hibernate, provides a means of mapping a logical function name to a delegate which knows how to render that particular function, perhaps even using a totally different physical function call.

This section scheduled for completion at a later date...