Hibernate.orgCommunity Documentation
Hibernate est conçu pour fonctionner dans de nombreux environnements , c'est pourquoi il existe beaucoup de paramètres de configuration. Heureusement, la plupart ont des valeurs par défaut appropriées et la Hibernate inclut un fichier d'exemples hibernate.properties
dans le répertoire etc/
qui fournit les différentes options. Vous n'avez qu'à placer ce fichier dans votre classpath et à l'adapter à vos besoins.
Une instance de org.hibernate.cfg.Configuration
représente un ensemble de mappages des classes Java d'une application vers la base de données SQL. La Configuration
est utilisée pour construire un objet (immuable) SessionFactory
. Les mappages sont constitués d'un ensemble de fichiers de mappage XML.
Vous pouvez obtenir une instance de Configuration
en l'instanciant directement et en spécifiant la liste des documents XML de mappage. Si les fichiers de mappage sont dans le classpath, vous pouvez utiliser la méthode addResource()
:
Configuration cfg = new Configuration()
.addResource("Item.hbm.xml")
.addResource("Bid.hbm.xml");
Une solution alternative consiste à spécifier la classe mappée et à donner à Hibernate la possibilité de trouver les documents de mappage pour vous :
Configuration cfg = new Configuration()
.addClass(org.hibernate.auction.Item.class)
.addClass(org.hibernate.auction.Bid.class);
Hibernate va rechercher les fichiers de mappages /org/hibernate/auction/Item.hbm.xml
et /org/hibernate/auction/Bid.hbm.xml
dans le classpath. Cette approche élimine les noms de fichiers en dur.
Une Configuration
vous permet également de préciser des propriétés de configuration. Par exemple :
Configuration cfg = new Configuration()
.addClass(org.hibernate.auction.Item.class)
.addClass(org.hibernate.auction.Bid.class)
.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
.setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
.setProperty("hibernate.order_updates", "true");
Ce n'est pas le seul moyen de passer des propriétés de configuration à Hibernate. Les différentes options sont :
Passer une instance de java.util.Properties
à Configuration.setProperties()
.
Placer hibernate.properties
dans un répertoire racine du chemin de classe.
Positionner les propriétés System
en utilisant java -Dproperty=value
.
Inclure des éléments <property>
dans le fichier hibernate.cfg.xml
(voir plus loin).
Si vous souhaitez démarrer rapidement, hibernate.properties
est l'approche la plus facile.
org.hibernate.cfg.Configuration
est un objet de démarrage qui sera supprimé une fois qu'une SessionFactory
aura été créée.
When all mappings have been parsed by the org.hibernate.cfg.Configuration
, the application must obtain a factory for org.hibernate.Session
instances. This factory is intended to be shared by all application threads:
SessionFactory sessions = cfg.buildSessionFactory();
Hibernate does allow your application to instantiate more than one org.hibernate.SessionFactory
. This is useful if you are using more than one database.
Il est conseillé que org.hibernate.SessionFactory
crée les connexions JDBC et les mette dans un pool pour vous. Si vous suivez cette approche, ouvrir une org.hibernate.Session
est aussi simple que :
Session session = sessions.openSession(); // open a new Session
Dès que vous initierez une action qui requiert un accès à la base de données, une connexion JDBC sera récupérée dans le pool.
À cet effet, il faut passer les propriétés de la connexion JDBC à Hibernate. Tous les noms des propriétés Hibernate et leur signification sont définies dans la classe org.hibernate.cfg.Environment
. Nous allons maintenant décrire les paramètres de configuration des connexions JDBC les plus importants.
Hibernate obtiendra des connexions (et les mettra dans un pool) en utilisant java.sql.DriverManager
si vous positionnez les paramètres de la manière suivante :
Tableau 3.1. Propriétés JDBC de Hibernate
Nom de la propriété | Fonction |
---|---|
hibernate.connection.driver_class | JDBC driver class |
hibernate.connection.url | JDBC URL |
hibernate.connection.username | database user |
hibernate.connection.password | database user password |
hibernate.connection.pool_size | maximum number of pooled connections |
L'algorithme natif de pool de connexions de Hibernate est plutôt rudimentaire. Il a été conçu dans le but de vous aider à démarrer et n'est pas prévu pour un système en production ou même pour un test de performance. Utilisez plutôt un pool tiers pour de meilleures performances et une meilleure stabilité : remplacez la propriété hibernate.connection.pool_size
avec les propriétés spécifiques au pool de connexions que vous avez choisi. Cela désactivera le pool de connexions interne de Hibernate. Vous pouvez par exemple utiliser C3P0.
C3P0 est un pool de connexions JDBC open source distribué avec Hibernate dans le répertoire lib
. Hibernate utilisera son provider C3P0ConnectionProvider
pour le pool de connexions si vous configurez les propriétés hibernate.c3p0.*
. Si vous voulez utiliser Proxool, référez vous au groupe de propriétés hibernate.properties
correspondant et consultez le site web Hibernate pour plus d'informations.
Voici un exemple de fichier hibernate.properties
pour C3P0:
hibernate.connection.driver_class = org.postgresql.Driver hibernate.connection.url = jdbc:postgresql://localhost/mydatabase hibernate.connection.username = myuser hibernate.connection.password = secret hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.timeout=1800 hibernate.c3p0.max_statements=50 hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
Pour l'utilisation de Hibernate au sein d'un serveur d'applications, il est recommandé de configurer Hibernate presque toujours de façon à ce qu'il obtienne ses connexions de la DataSource
enregistrée du serveur d'applications dans le JNDI. À cet effet, vous devrez définir au moins une des propriétés suivantes :
Tableau 3.2. Propriétés d'une Datasource Hibernate
Nom de la propriété | Fonction |
---|---|
hibernate.connection.datasource | datasource JNDI name |
hibernate.jndi.url | URL du fournisseur JNDI (optionnel) |
hibernate.jndi.class | classe de JNDI InitialContextFactory (optionnel) |
hibernate.connection.username | utilisateur de base de données (optionnel) |
hibernate.connection.password | mot de passe de l'utilisateur de base de données (optionnel) |
Voici un exemple de fichier hibernate.properties
pour l'utilisation d'une datasource JNDI fournie par un serveur d'applications :
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
Les connexions JDBC obtenues à partir d'une datasource JNDI participeront automatiquement aux transactions gérées par le conteneur du serveur d'applications.
Des propriétés arbitraires de connexion peuvent être passées en préfixant le nom de la propriété par "hibernate.connnection
". Par exemple, vous pouvez spécifier un charSet
en utilisant hibernate.connection.charSet
.
Vous pouvez fournir votre propre stratégie d'obtention des connexions JDBC en implémentant l'interface org.hibernate.connection.ConnectionProvider
. Vous pouvez sélectionner une implémentation spécifique par la propriété hibernate.connection.provider_class
.
Il y a un certain nombre d'autres propriétés qui contrôlent le fonctionnement d'Hibernate à l'exécution. Toutes sont optionnelles et ont comme valeurs par défaut des valeurs raisonnables.
Some of these properties are "system-level" only. System-level properties can be set only via java -Dproperty=value
or hibernate.properties
. They cannot be set by the other techniques described above.
Tableau 3.3. Propriétés de configuration Hibernate
Nom de la propriété | Fonction |
---|---|
hibernate.dialect | Le nom de la classe d'un org.hibernate.dialect.Dialect Hibernate qui permet à Hibernate de générer du SQL optimisé pour une base de données relationnelle particulière. par ex. Dans la plupart des cas, Hibernate sera en mesure de choisir l'implémentation |
hibernate.show_sql | Écrit toutes les requêtes SQL sur la console. Il s'agit d'une alternative au paramétrage de la catégorie de log org.hibernate.SQL à debug . par ex. |
hibernate.format_sql | Effectue un pretty print du SQL dans la console et dans le log. par ex. |
hibernate.default_schema | Qualifie des noms de table non qualifiés avec le schéma/tablespace dans le SQL généré. e.g. |
hibernate.default_catalog | Qualifie les noms de tables non qualifiées avec ce catalogue dans le SQL généré. e.g. |
hibernate.session_factory_name | org.hibernate.SessionFactory sera automatiquement liée à ce nom dans JNDI après sa création. par ex. |
hibernate.max_fetch_depth | Configure la profondeur maximale d'un arbre de chargement par jointures externes pour les associations à cardinalité unitaire (un-à-un, plusieurs-à-un). Un 0 désactive le chargement par défaut par jointure externe. par ex. valeurs recommandées entre |
hibernate.default_batch_fetch_size | Configure une taille par défaut pour le chargement par lot des associations Hibernate ex. valeurs recommandées : |
hibernate.default_entity_mode | Sets a default mode for entity representation for all sessions opened from this SessionFactory
|
hibernate.order_updates | Force Hibernate à trier les mises à jour SQL par la valeur de la clé primaire des éléments mis à jour. Cela permet de limiter les deadlocks de transaction dans les systèmes hautement concurrents. par ex. |
hibernate.generate_statistics | Si activé, Hibernate va collecter des statistiques utiles pour le réglage des performances. par ex. |
hibernate.use_identifier_rollback | Si activé, les propriétés correspondant à l'identifiant des objets sont remises aux valeurs par défaut lorsque les objets sont supprimés. par ex. |
hibernate.use_sql_comments | Si activé, Hibernate génère des commentaires à l'intérieur des requêtes SQL pour faciliter le débogage, par défaut à false . par ex. |
Tableau 3.4. Propriétés Hibernate liées à JDBC et aux connexions
Nom de la propriété | Fonction |
---|---|
hibernate.jdbc.fetch_size | Une valeur non nulle détermine la taille des chargements JDBC (appelle Statement.setFetchSize() ). |
hibernate.jdbc.batch_size | Une valeur non nulle active l'utilisation par Hibernate des mise à jour par lot de JDBC2. ex. les valeurs recommandées entre |
hibernate.jdbc.batch_versioned_data | Set this property to true if your JDBC driver returns correct row counts from executeBatch() . It is usually safe to turn this option on. Hibernate will then use batched DML for automatically versioned data. Defaults to false . par ex. |
hibernate.jdbc.factory_class | Sélectionne un org.hibernate.jdbc.Batcher personnalisé. La plupart des applications n'auront pas besoin de cette propriété de configuration. par.ex. |
hibernate.jdbc.use_scrollable_resultset | Active l'utilisation par Hibernate des ensembles de résultats déroulants de JDBC2. Cette propriété est seulement nécessaire lorsque l'on utilise des connexions JDBC fournies par l'utilisateur. Autrement, Hibernate utilise les métadonnées de la connexion. par ex. |
hibernate.jdbc.use_streams_for_binary | Utilise des flux lorsque l'on écrit/lit des types binary ou des types serializable vers/à partir de JDBC. *system-level property* par ex. |
hibernate.jdbc.use_get_generated_keys | Active l'utilisation de PreparedStatement.getGeneratedKeys() de JDBC3 pour récupérer nativement les clés générées après insertion. Nécessite un pilote JDBC3+ et JRE1.4+, configurés à false si votre pilote a des problèmes avec les générateurs d'identifiant Hibernate. Par défaut, essaie de déterminer les possibilités du pilote en utilisant les metadonnées de connexion. par ex. |
hibernate.connection.provider_class | Le nom de la classe d'un org.hibernate.connection.ConnectionProvider personnalisé qui fournit des connexions JDBC à Hibernate. par ex. |
hibernate.connection.isolation | Définit le niveau d'isolation des transactions JDBC. Regardez java.sql.Connection pour des valeurs significatives mais notez également que la plupart des bases de données ne supportent pas tous les niveaux d'isolation et que certaines définissent des isolations non standard supplémentaires. par ex. |
hibernate.connection.autocommit | Active le mode de commit automatique (autocommit) pour les connexions JDBC du pool (non recommandé). par ex. |
hibernate.connection.release_mode | Spécifie à quel moment Hibernate doit relâcher les connexions JDBC. Par défaut, une connexion JDBC est conservée jusqu'à ce que la session soit explicitement fermée ou déconnectée. Pour une source de données JTA d'un serveur d'applications, vous devriez utiliser after_statement pour libérer les connexions de manière plus agressive après chaque appel JDBC. Pour une connexion non JTA, il est souvent préférable de libérer la connexion à la fin de chaque transaction en utilisant after_transaction . auto choisira after_statement pour les stratégies de transactions JTA et CMT et after_transaction pour des stratégies de transactions JDBC. e.g. This setting only affects |
hibernate.connection.<propertyName> | Passez une propriété JDBC propertyName à DriverManager.getConnection() . |
hibernate.jndi.<propertyName> | Passez la propriété <propertyName> au JNDI InitialContextFactory . |
Tableau 3.5. Propriétés du Cache Hibernate
Nom de la propriété | Fonction |
---|---|
hibernate.cache.provider_class
| Le nom de classe d'un CacheProvider personnalisé. par ex. |
hibernate.cache.use_minimal_puts
| Optimise le cache de second niveau en minimisant les écritures, au prix de plus de lectures. Ce paramètre est surtout utile pour les caches en cluster,et est activé par défaut dans hibernate3 pour les implémentations de cache en cluster. par ex. |
hibernate.cache.use_query_cache
| Activer le cache de requête, les requêtes individuelles doivent tout de même être déclarées comme pouvant être mises en cache. par ex. |
hibernate.cache.use_second_level_cache
| Peut être utilisé pour désactiver complètement le cache de second niveau qui est activé par défaut pour les classes qui spécifient un élément <cache> dans leur mappage. par ex. |
hibernate.cache.query_cache_factory
| Le nom de classe d'une interface QueryCache personnalisée, par défaut prend la valeur du StandardQueryCache imbriqué. par ex. |
hibernate.cache.region_prefix
| Un préfixe à utiliser pour les noms de régions du cache de second niveau. par ex. |
hibernate.cache.use_structured_entries
| Force Hibernate à stocker les données dans le cache de second niveau en un format plus adapté à la visualisation. par ex. |
Tableau 3.6. Propriétés des transactions Hibernate
Nom de la propriété | Fonction |
---|---|
hibernate.transaction.factory_class
| Le nom de classe d'une TransactionFactory qui sera utilisée par l'API Transaction de Hibernate (la valeur par défaut est JDBCTransactionFactory ). par ex. |
jta.UserTransaction
| Le nom JNDI utilisé par la JTATransactionFactory pour obtenir la UserTransaction JTA du serveur d'applications. par ex. |
hibernate.transaction.manager_lookup_class
| Le nom de la classe d'une TransactionManagerLookup - requise lorsque le cache de niveau JVM est activé ou lorsque l'on utilise un générateur hilo dans un environnement JTA. par ex. |
hibernate.transaction.flush_before_completion
| If enabled, the session will be automatically flushed during the before completion phase of the transaction. Built-in and automatic session context management is preferred, see Section 2.5, « Sessions contextuelles ». par ex. |
hibernate.transaction.auto_close_session
| If enabled, the session will be automatically closed during the after completion phase of the transaction. Built-in and automatic session context management is preferred, see Section 2.5, « Sessions contextuelles ». par ex. |
Tableau 3.7. Propriétés diverses
Nom de la propriété | Fonction |
---|---|
hibernate.current_session_context_class
| Supply a custom strategy for the scoping of the "current" Session . See Section 2.5, « Sessions contextuelles » for more information about the built-in strategies. e.g. |
hibernate.query.factory_class
| Choisit l'implémentation du parseur de requête HQL. par ex. |
hibernate.query.substitutions
| Lien entre les jetons de requêtes Hibernate et les jetons SQL (les jetons peuvent être des fonctions ou des noms textuels par exemple). par ex. |
hibernate.hbm2ddl.auto
| Valide ou exporte automatiquement le schéma DDL vers la base de données lorsque la SessionFactory est créée. La valeur create-drop permet de supprimer le schéma de base de données lorsque la SessionFactory est fermée explicitement. par ex. |
hibernate.bytecode.use_reflection_optimizer
|
Enables the use of bytecode manipulation instead of runtime reflection. This is a System-level property and cannot be set in par ex. |
hibernate.bytecode.provider
| Both javassist or cglib can be used as byte manipulation engines; the default is e.g. |
Il est recommandé de toujours positionner la propriété hibernate.dialect
à la sous-classe de org.hibernate.dialect.Dialect
appropriée à votre base de données. Si vous spécifiez un dialecte, Hibernate utilisera des valeurs adaptées pour certaines autres propriétés listées ci-dessus, vous évitant ainsi de l'effectuer à la main.
Tableau 3.8. Dialectes SQL de Hibernate (hibernate.dialect
)
RDBMS | Dialecte |
---|---|
DB2 | org.hibernate.dialect.DB2Dialect |
DB2 AS/400 | org.hibernate.dialect.DB2400Dialect |
DB2 OS390 | org.hibernate.dialect.DB2390Dialect |
PostgreSQL | org.hibernate.dialect.PostgreSQLDialect |
MySQL | org.hibernate.dialect.MySQLDialect |
MySQL with InnoDB | org.hibernate.dialect.MySQLInnoDBDialect |
MySQL with MyISAM | org.hibernate.dialect.MySQLMyISAMDialect |
Oracle (toutes versions) | org.hibernate.dialect.OracleDialect |
Oracle 9i | org.hibernate.dialect.Oracle9iDialect |
Oracle 10g | org.hibernate.dialect.Oracle10gDialect |
Sybase | org.hibernate.dialect.SybaseDialect |
Sybase Anywhere | org.hibernate.dialect.SybaseAnywhereDialect |
Microsoft SQL Server | org.hibernate.dialect.SQLServerDialect |
SAP DB | org.hibernate.dialect.SAPDBDialect |
Informix | org.hibernate.dialect.InformixDialect |
HypersonicSQL | org.hibernate.dialect.HSQLDialect |
Ingres | org.hibernate.dialect.IngresDialect |
Progress | org.hibernate.dialect.ProgressDialect |
Mckoi SQL | org.hibernate.dialect.MckoiDialect |
Interbase | org.hibernate.dialect.InterbaseDialect |
Pointbase | org.hibernate.dialect.PointbaseDialect |
FrontBase | org.hibernate.dialect.FrontbaseDialect |
Firebird | org.hibernate.dialect.FirebirdDialect |
Si votre base de données supporte les jointures externes de type ANSI, Oracle ou Sybase, le chargement par jointure externe devrait améliorer les performances en limitant le nombre d'aller-retour avec la base de données (la base de données effectuant donc potentiellement plus de travail). Le chargement par jointure ouverte permet à un graphe entier d'objets connectés par une relation plusieurs-à-un, un-à-plusieurs ou un-à-un d'être chargé en un seul SQLSELECT
.
Le chargement par jointure ouverte peut être désactivé globalement en mettant la propriété hibernate.max_fetch_depth
à 0
. Une valeur de 1
ou plus active le chargement par jointure externe pour les associations un-à-un et plusieurs-à-un qui ont été mappées avec fetch="join"
.
See Section 20.1, « Stratégies de chargement » for more information.
Oracle limite la taille d'un tableau d'octets
qui peuvent être passés vers et à partir de son pilote JDBC. Si vous souhaitez utiliser des instances larges de type binary
ou serializable
, vous devez activer la propriété hibernate.jdbc.use_streams_for_binary
. C'est une fonctionalité de niveau système uniquement.
The properties prefixed by hibernate.cache
allow you to use a process or cluster scoped second-level cache system with Hibernate. See the Section 20.2, « Le cache de second niveau » for more information.
Vous pouvez définir de nouveaux jetons dans les requêtes Hibernate en utilisant hibernate.query.substitutions
. Par exemple :
hibernate.query.substitutions true=1, false=0
Cela signifierait que les jetons true
et false
seraient transformés par des entiers dans le SQL généré.
hibernate.query.substitutions toLowercase=LOWER
Cela permettrait de renommer la fonction SQL LOWER
.
Si vous activez hibernate.generate_statistics
, Hibernate fournira un certain nombre de métriques utiles pour régler les performances d'une application qui tourne via SessionFactory.getStatistics()
. Hibernate peut aussi être configuré pour exposer ces statistiques via JMX. Lisez les Javadoc des interfaces dans le paquetage org.hibernate.stats
pour plus d'informations.
Hibernate utilise Simple Logging Facade for Java (SLF4J) pour enregistrer divers événements du système. SLF4J peut diriger votre sortie de logging vers plusieurs structures de loggings (NOP, Simple, log4j version 1.2, JDK 1.4 logging, JCL or logback) suivant la liaison que vous choisirez. Pour pouvoir configurer votre logging, vous aurez besoin de slf4j-api.jar
dans votre chemin de classe, ainsi que du fichier jar pour votre liaison préférée - slf4j-log4j12.jar
pour Log4J. Voir la documentation SLF4J documentation pour davantage d'informations. Pour utiliser Log4j, vous aurez aussi besoin de mettre un fichier log4j.properties
dans votre chemin de classe. Un exemple de fichier de propriétés est distribué avec Hibernate dans le répertoire src/
.
Il est vivement recommandé de vous familiariser avec les messages des logs de Hibernate. Beaucoup de soin a été apporté pour donner le plus de détails possible sans les rendre illisibles. C'est un outil essentiel en cas de problèmes. Les catégories de logs les plus intéressantes sont les suivantes :
Tableau 3.9. Catégories de logs de Hibernate
Catégorie | Fonction |
---|---|
org.hibernate.SQL | Journalise toutes les requêtes SQL de type DML (gestion des données) qui sont exécutées |
org.hibernate.type | Journalise tous les paramètres JDBC |
org.hibernate.tool.hbm2ddl | Journalise toutes les requêtes SQL de type DDL (gestion de la structure de la base) qui sont exécutées |
org.hibernate.pretty | Journalise l'état de toutes les entités (20 entités maximum) associées avec la session Hibernate au moment du flush |
org.hibernate.cache | Journalise toute activité du cache de second niveau |
org.hibernate.transaction | Journalise toute activité relative aux transactions |
org.hibernate.jdbc | Journalise toute acquisition de ressource JDBC |
org.hibernate.hql.ast.AST | Journalise l'arbre syntaxique des requêtes HQL et SQL durant l'analyse syntaxique des requêtes |
org.hibernate.secure | Journalise toutes les demandes d'autorisation JAAS |
org.hibernate | Journalise tout (beaucoup d'informations, mais très utile pour résoudre les problèmes). |
Lorsque vous développez des applications avec Hibernate, vous devriez quasiment toujours travailler avec le niveau debug
activé pour la catégorie org.hibernate.SQL
, ou sinon avec la propriété hibernate.show_sql
activée.
L'interface org.hibernate.cfg.NamingStrategy
vous permet de spécifier une "stratégie de nommage" des objets et éléments de la base de données.
Vous pouvez fournir des règles pour automatiquement générer les identifiants de base de données à partir des identifiants Java, ou transformer une colonne ou table "logique" donnée dans le fichier de mappage en une colonne ou table "physique". Cette fonctionnalité aide à réduire la verbosité de documents de mappage, en éliminant le bruit répétitif (les préfixes TBL_
par exemple). La stratégie par défaut utilisée par Hibernate est assez minimale.
Vous pouvez définir une stratégie différente en appelant Configuration.setNamingStrategy()
avant d'ajouter des mappages :
SessionFactory sf = new Configuration()
.setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
.addFile("Item.hbm.xml")
.addFile("Bid.hbm.xml")
.buildSessionFactory();
net.sf.hibernate.cfg.ImprovedNamingStrategy
est une stratégie fournie qui peut être utile comme point de départ de quelques applications.
Une approche alternative est de spécifier toute la configuration dans un fichier nommé hibernate.cfg.xml
. Ce fichier peut être utilisé à la place du fichier hibernate.properties
, voire même peut servir à surcharger les propriétés si les deux fichiers sont présents.
Le fichier de configuration XML doit par défaut se placer à la racine du CLASSPATH
. En voici un exemple :
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory
name="java:hibernate/SessionFactory">
<!-- properties -->
<property name="connection.datasource"
>java:/comp/env/jdbc/MyDB</property>
<property name="dialect"
>org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql"
>false</property>
<property name="transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="jta.UserTransaction"
>java:comp/UserTransaction</property>
<!-- mapping files -->
<mapping resource="org/hibernate/auction/Item.hbm.xml"/>
<mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
<!-- cache settings -->
<class-cache class="org.hibernate.auction.Item" usage="read-write"/>
<class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
<collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
</session-factory>
</hibernate-configuration
>
Comme vous pouvez le constater, l'avantage de cette approche est l'externalisation des noms des fichiers de mappage de la configuration. Le fichier hibernate.cfg.xml
est également plus pratique quand on commence à régler le cache d'Hibernate. Notez que vous pouvez choisir entre utiliser hibernate.properties
ou hibernate.cfg.xml
, les deux sont équivalents, sauf en ce qui concerne les bénéfices de l'utilisation de la syntaxe XML mentionnés ci-dessus.
Avec la configuration XML, démarrer Hibernate devient donc aussi simple que ceci :
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Vous pouvez choisir un fichier de configuration XML différent en utilisant :
SessionFactory sf = new Configuration()
.configure("catdb.cfg.xml")
.buildSessionFactory();
Hibernate possède les points d'intégration suivants pour l'infrastructure J2EE :
Source de données gérée par le conteneur : Hibernate peut utiliser des connexions JDBC gérées par le conteneur et fournies par l'intermédiaire de JNDI. Souvent, un TransactionManager
compatible JTA et un ResourceManager
s'occupent de la gestion des transactions (CMT). Ils sont conçus en particulier pour gérer des transactions distribuées sur plusieurs sources de données. Vous pouvez biensûr également définir les limites des transactions dans votre programme (BMT) ou vous pouvez par ailleurs utiliser l'API optionnelle Transaction
de Hibernate qui vous garantira la portabilité de votre code entre plusieurs serveurs d'application.
Association JNDI automatique: Hibernate peut associer sa SessionFactory
à JNDI après le démarrage.
Association de la Session à JTA: la Session
Hibernate peut être automatiquement associée à la portée des transactions JTA si vous utilisez les EJB. Vous avez juste à récupérer la SessionFactory
depuis JNDI et à récupérer la Session
courante. Hibernate s'occupe de vider et fermer la Session
lorsque votre transaction JTA se termine. La démarcation des transactions se fait de manière déclarative (CMT) ou de façon programmatique (BMT/UserTransaction).
Déploiement JMX :Si vous avez un serveur d'applications compatible JMX (JBoss AS par exemple), vous pouvez choisir de déployer Hibernate en tant que MBean géré par le serveur. Cela vous évite de coder la ligne de démarrage qui permet de construire la SessionFactory
depuis la Configuration
. Le conteneur va démarrer votre HibernateService
, et va idéalement s'occuper des dépendances entre les services (la source de données doit être disponible avant le démarrage de Hibernate, etc).
En fonction de votre environnement, vous mettrez l'option de configuration hibernate.connection.aggressive_release
à true si le serveur d'applications affiche des exceptions de type "connection containment".
L'API de la Session
Hibernate est indépendante de tout système de démarcation des transactions, présent dans votre architecture. Si vous laissez Hibernate utiliser l'API JDBC directement via un pool de connexion, vous commencerez et terminerez vos transactions en appelant l'API JDBC. Si votre application tourne à l'intérieur d'un serveur d'applications J2EE, vous utiliserez peut être les transactions gérées par les beans (BMT) et vous appellerez l'API JTA et UserTransaction
lorsque cela est nécessaire.
Pour conserver votre code portable entre ces deux environnements (et d'autres), nous vous recommandons d'utiliser l'API optionnelle Transaction
d'Hibernate, qui encapsule et masque le système de transaction sous-jacent. Pour cela, vous devez préciser une classe de fabrique d'instances de Transaction
en positionnant la propriété de configuration hibernate.transaction.factory_class
.
Il existe trois choix standards (intégrés) :
org.hibernate.transaction.JDBCTransactionFactory
délègue aux transactions de la base de données (JDBC) (valeur par défaut).
org.hibernate.transaction.JTATransactionFactory
délègue à CMT si une transaction existante est sous ce contexte (par ex : méthode d'un EJB session), sinon une nouvelle transaction est entamée et une transaction gérée par le bean est utilisée.
org.hibernate.transaction.CMTTransactionFactory
délègue aux transactions JTA gérées par le conteneur
Vous pouvez également définir vos propres stratégies transactionnelles (pour un service de transaction CORBA par exemple).
Certaines fonctionnalités de Hibernate (c'est-à-dire le cache de second niveau, l'association automatique des Sessions à JTA, etc.) nécessitent l'accès au TransactionManager
JTA dans un environnement géré. Dans un serveur d'applications, vous devez indiquer comment Hibernate peut obtenir une référence vers le TransactionManager
, car J2EE ne fournit pas un seul mécanisme standard.
Tableau 3.10. TransactionManagers JTA
Fabrique de transaction | Serveur d'applications |
---|---|
org.hibernate.transaction.JBossTransactionManagerLookup | JBoss |
org.hibernate.transaction.WeblogicTransactionManagerLookup | Weblogic |
org.hibernate.transaction.WebSphereTransactionManagerLookup | WebSphere |
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup | WebSphere 6 |
org.hibernate.transaction.OrionTransactionManagerLookup | Orion |
org.hibernate.transaction.ResinTransactionManagerLookup | Resin |
org.hibernate.transaction.JOTMTransactionManagerLookup | JOTM |
org.hibernate.transaction.JOnASTransactionManagerLookup | JOnAS |
org.hibernate.transaction.JRun4TransactionManagerLookup | JRun4 |
org.hibernate.transaction.BESTransactionManagerLookup | Borland ES |
Une SessionFactory
Hibernate associée au JNDI peut simplifier l'accès à la fabrique et donc la création de nouvelles Session
s. Notez que cela n'est pas lié avec les Datasource
associées au JNDI, elles utilisent juste le même registre !
Si vous désirez associer la SessionFactory
à un nom JNDI, spécifiez un nom (par ex. java:hibernate/SessionFactory
) en utilisant la propriété hibernate.session_factory_name
. Si cette propriété est omise, la SessionFactory
ne sera pas associée au JNDI (c'est particulièrement pratique dans les environnements ayant une implémentation JNDI par défaut en lecture seule, comme c'est le cas pour Tomcat).
Lorsqu'il associe la SessionFactory
au JNDI, Hibernate utilisera les valeurs de hibernate.jndi.url
, hibernate.jndi.class
pour instancier un contexte d'initialisation. S'ils ne sont pas spécifiés, l'InitialContext
par défaut sera utilisé.
Hibernate va automatiquement placer la SessionFactory
dans JNDI après avoir appelé cfg.buildSessionFactory()
. Cela signifie que vous devez avoir cet appel dans un code de démarrage (ou dans une classe utilitaire) dans votre application sauf si vous utilisez le déploiement JMX avec le service HibernateService
présenté plus tard dans ce document.
Si vous utilisez SessionFactory
JNDI, un EJB ou n'importe quelle autre classe peut obtenir la SessionFactory
en utilisant une recherche JNDI.
Nous recommandons de lier la SessionFactory
à JNDI dans les environnements gérés et d'utilisier un singleton static
si ce n'est pas le cas. Pour isoler votre application de ces détails, nous vous recommandons aussi de masquer le code de recherche actuel pour une SessionFactory
dans une classe helper, comme HibernateUtil.getSessionFactory()
. Notez qu'une telle classe est aussi un moyen efficace de démarrer Hibernate - voir chapitre 1.
The easiest way to handle Sessions
and transactions is Hibernate's automatic "current" Session
management. For a discussion of contextual sessions see Section 2.5, « Sessions contextuelles ». Using the "jta"
session context, if there is no Hibernate Session
associated with the current JTA transaction, one will be started and associated with that JTA transaction the first time you call sessionFactory.getCurrentSession()
. The Session
s retrieved via getCurrentSession()
in the "jta"
context are set to automatically flush before the transaction completes, close after the transaction completes, and aggressively release JDBC connections after each statement. This allows the Session
s to be managed by the life cycle of the JTA transaction to which it is associated, keeping user code clean of such management concerns. Your code can either use JTA programmatically through UserTransaction
, or (recommended for portable code) use the Hibernate Transaction
API to set transaction boundaries. If you run in an EJB container, declarative transaction demarcation with CMT is preferred.
La ligne cfg.buildSessionFactory()
doit toujours être exécutée quelque part pour obtenir une SessionFactory
dans JNDI. Vous pouvez faire cela dans un bloc d'initialisation static
(comme celui qui se trouve dans la classe HibernateUtil
) ou vous pouvez déployer Hibernate en temps que service géré.
Hibernate est distribué avec org.hibernate.jmx.HibernateService
pour le déploiement sur un serveur d'applications avec le support de JMX comme JBoss AS. Le déploiement et la configuration sont spécifiques à chaque vendeur. Voici un fichier jboss-service.xml
d'exemple pour JBoss 4.0.x :
<?xml version="1.0"?>
<server>
<mbean code="org.hibernate.jmx.HibernateService"
name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
<!-- Required services -->
<depends
>jboss.jca:service=RARDeployer</depends>
<depends
>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
<!-- Bind the Hibernate service to JNDI -->
<attribute name="JndiName"
>java:/hibernate/SessionFactory</attribute>
<!-- Datasource settings -->
<attribute name="Datasource"
>java:HsqlDS</attribute>
<attribute name="Dialect"
>org.hibernate.dialect.HSQLDialect</attribute>
<!-- Transaction integration -->
<attribute name="TransactionStrategy">
org.hibernate.transaction.JTATransactionFactory</attribute>
<attribute name="TransactionManagerLookupStrategy">
org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
<attribute name="FlushBeforeCompletionEnabled"
>true</attribute>
<attribute name="AutoCloseSessionEnabled"
>true</attribute>
<!-- Fetching options -->
<attribute name="MaximumFetchDepth"
>5</attribute>
<!-- Second-level caching -->
<attribute name="SecondLevelCacheEnabled"
>true</attribute>
<attribute name="CacheProviderClass"
>org.hibernate.cache.EhCacheProvider</attribute>
<attribute name="QueryCacheEnabled"
>true</attribute>
<!-- Logging -->
<attribute name="ShowSqlEnabled"
>true</attribute>
<!-- Mapping files -->
<attribute name="MapResources"
>auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
</mbean>
</server
>
Ce fichier est déployé dans un répertoire META-INF
et est empaqueté dans un fichier JAR avec l'extension .sar
(service archive). Vous devez également empaqueter Hibernate, les librairies tierces requises, vos classes persistantes compilées et vos fichiers de mappage dans la même archive. Vos beans entreprise (souvent des EJB session) peuvent rester dans leur propre fichier JAR mais vous pouvez inclure ce fichier JAR dans le jar principal du service pour avoir une seule unité déployable à chaud. Vous pouvez consulter la documentation de JBoss AS pour plus d'informations sur les services JMX et le déploiement des EJB.
Copyright © 2004 Red Hat, Inc.