Chapitre 20. Guide des outils

Des outils en ligne de commande, des plugins Eclipse ainsu que des tâches Ant permettent de gérer de cycles de développement complet de projets utilisant Hibernate.

Les outils Hibernate actuels incluent des plugins pour l'IDE Eclipse ainsi que des tâches Ant pour l'ingénierie inverse de bases de données existantes :

Veuillez-vous référer au paquet outils Hibernate et sa documentation pour plus d'informations.

Pourtant, le paquet principal d'Hibernate arrive avec un lot d'outils intégrés (il peut même être utilisé de "l'intérieur" d'Hibernate à la volée) : SchemaExport aussi connu comme hbm2ddl.

20.1. Génération automatique du schéma

La DDL peut être générée à partir de vos fichiers de mapping par un utilitaire d'Hibernate. Le schéma généré inclut les contraintes d'intégrité référentielle (clefs primaires et étrangères) pour les tables d'entités et de collections. Les tables et les séquences sont aussi créées pour les générateurs d'identifiant mappés.

Vous devez spécifier un Dialect SQL via la propriété hibernate.dialect lors de l'utilisation de cet outils, puisque la DDL est fortement dépendante de la base de données.

D'abord, personnalisez vos fichiers de mapping pour améliorer le schéma généré.

20.1.1. Personnaliser le schéma

Plusieurs éléments du mapping hibernate définissent des attributs optionnels nommés length, precision et scale. Vous pouvez paramétrer la longueur, la précision,... d'une colonne avec ces attributs.

<property name="zip" length="5"/>
<property name="balance" precision="12" scale="2"/>

Certains éléments acceptent aussi un attribut not-null (utilisé pour générer les contraintes de colonnes NOT NULL) et un attribut unique (pour générer une contrainte de colonne UNIQUE).

<many-to-one name="bar" column="barId" not-null="true"/>
<element column="serialNumber" type="long" not-null="true" unique="true"/>

Un attribut unique-key peut être utilisé pour grouper les colonnes en une seule contrainte d'unicité. Actuellement, la valeur spécifiée par l'attribut unique-key n'est pas utilisée pour nommer la contrainte dans le DDL généré, elle sert juste à grouper les colonnes dans le fichier de mapping.

<many-to-one name="org" column="orgId" unique-key="OrgEmployeeId"/>
<property name="employeeId" unique-key="OrgEmployee"/>

Un attribut index indique le nom d'un index qui sera créé en utilisant la ou les colonnes mappées. Plusieurs colonnes peuvent être groupées dans un même index, en spécifiant le même nom d'index.

<property name="lastName" index="CustName"/>
<property name="firstName" index="CustName"/>

Un attribut foreign-key peut être utilisé pour surcharger le nom des clés étrangères générées.

<many-to-one name="bar" column="barId" foreign-key="FKFooBar"/>

Plusieurs éléments de mapping acceptent aussi un élément fils <column>. Ceci est utile pour les type multi-colonnes:

<property name="name" type="my.customtypes.Name"/>
    <column name="last" not-null="true" index="bar_idx" length="30"/>
    <column name="first" not-null="true" index="bar_idx" length="20"/>
    <column name="initial"/>
</property>

L'attribut default vous laisse spécifier une valeur par défaut pour une colonnes (vous devriez assigner la même valeur à la propriété mappée avant de sauvegarder une nouvelle instance de la classe mappée).

<property name="credits" type="integer" insert="false">
    <column name="credits" default="10"/>
</property>
<version name="version" type="integer" insert="false">
    <column name="version" default="0"/>
</property>

L'attribut sql-type laisse l'utilisateur surcharger le mapping par défaut du type Hibernate vers un type SQL.

<property name="balance" type="float">
    <column name="balance" sql-type="decimal(13,3)"/>
</property>

L'attribut check permet de spécifier une contrainte de vérification.

<property name="foo" type="integer">
    <column name="foo" check="foo > 10"/>
</property>
<class name="Foo" table="foos" check="bar < 100.0">
    ...
    <property name="bar" type="float"/>
</class>

Tableau 20.1. Summary

Attribut Valeur Interprétation
length numérique taille d'une colonne
precision numérique précision décimale de la colonne
scale numérique scale décimale de la colonne
not-null true|false spécifie que la colonne doit être non-nulle
unique true|false spécifie que la colonne doit avoir une contrainte d'unicité
index index_name spécifie le nom d'un index (multi-colonnes)
unique-key unique_key_name spécifie le nom d'une contrainte d'unicité multi-colonnes
foreign-key foreign_key_name specifies the name of the foreign key constraint generated for an association, for a <one-to-one>, <many-to-one>, <key>, or <many-to-many> mapping element. Note that inverse="true" sides will not be considered by SchemaExport.
sql-type SQL column_type overrides the default column type (attribute of <column> element only)
default SQL expression spécifie une valeur par défaut pour la colonne
check SQL expression crée une contrainte de vérification sur la table ou la colonne

L'élément <comment> vous permet de spécifier un commentaire pour le schéma généré.

<class name="Customer" table="CurCust">
    <comment>Current customers only</comment>
    ...
</class>
<property name="balance">
    <column name="bal">
        <comment>Balance in USD</comment>
    </column>
</property>

Ceci a pour résultat une expression comment on table ou comment on column dans la DDL générée (où supportée).

20.1.2. Exécuter l'outil

L'outil SchemaExport génère un script DDL vers la sortie standard et/ou exécute les ordres DDL.

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaExport options mapping_files

Tableau 20.2. SchemaExport Options de la ligne de commande

Option Description
--quiet don't output the script to stdout
--drop supprime seuleument les tables
--create ne créé que les tables
--text ne pas exécuter sur la base de données
--output=my_schema.ddl écrit le script ddl vers un fichier
--naming=eg.MyNamingStrategy select a NamingStrategy
--config=hibernate.cfg.xml lit la configuration Hibernate à partir d'un fichier XML
--properties=hibernate.properties read database properties from a file
--format formatte proprement le SQL généré dans le script
--delimiter=x paramètre un délimiteur de fin de ligne pour le script

Vous pouvez même intégrer SchemaExport dans votre application :

Configuration cfg = ....;
new SchemaExport(cfg).create(false, true);

20.1.3. Propriétés

Les propriétés de la base de données peuvent être spécifiées

  • comme propriétés système avec -D<property>

  • dans hibernate.properties

  • dans un fichier de propriétés déclaré avec --properties

Les propriétés nécessaires sont :

Tableau 20.3. SchemaExport Connection Properties

Nom de la propriété Description
hibernate.connection.driver_class classe du driver JDBC
hibernate.connection.url URL JDBC
hibernate.connection.username utilisateur de la base de données
hibernate.connection.password mot de passe de l'utilisateur
hibernate.dialect dialecte

20.1.4. Utiliser Ant

Vous pouvez appeler SchemaExport depuis votre script de construction Ant :

<target name="schemaexport">
    <taskdef name="schemaexport"
        classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
        classpathref="class.path"/>
    
    <schemaexport
        properties="hibernate.properties"
        quiet="no"
        text="no"
        drop="no"
        delimiter=";"
        output="schema-export.sql">
        <fileset dir="src">
            <include name="**/*.hbm.xml"/>
        </fileset>
    </schemaexport>
</target>

20.1.5. Mises à jour incrémentales du schéma

L'outil SchemaUpdate mettra à jour un schéma existant en effectuant les changement par "incrément". Notez que SchemaUpdate dépends beaucoup de l'API JDBC metadata, il ne fonctionnera donc pas avec tous les drivers JDBC.

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaUpdate options mapping_files

Tableau 20.4. SchemaUpdate Options de ligne de commande

Option Description
--quiet don't output the script to stdout
--text ne pas exporter vers la base de données
--naming=eg.MyNamingStrategy select a NamingStrategy
--properties=hibernate.properties read database properties from a file
--config=hibernate.cfg.xml specify a .cfg.xml file

Vous pouvez intégrer SchemaUpdate dans votre application :

Configuration cfg = ....;
new SchemaUpdate(cfg).execute(false);

20.1.6. Utiliser Ant pour des mises à jour de schéma par incrément

Vous pouvez appeler SchemaUpdate depuis le script Ant :

<target name="schemaupdate">
    <taskdef name="schemaupdate"
        classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
        classpathref="class.path"/>
    
    <schemaupdate
        properties="hibernate.properties"
        quiet="no">
        <fileset dir="src">
            <include name="**/*.hbm.xml"/>
        </fileset>
    </schemaupdate>
</target>

20.1.7. Validation du schéma

L'outil SchemaValidator validera que le schéma existant correspond à vos documents de mapping. Notez que le SchemaValidator dépends de l'API metadata de JDBC, il ne fonctionnera donc pas avec tous les drivers JDBC. Cet outil est extrêmement utile pour tester.

java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaValidator options mapping_files

Tableau 20.5. SchemaValidator Options de ligne de commande

Option Description
--naming=eg.MyNamingStrategy select a NamingStrategy
--properties=hibernate.properties read database properties from a file
--config=hibernate.cfg.xml specify a .cfg.xml file

Vous pouvez inclure SchemaValidator dans votre application:

Configuration cfg = ....;
new SchemaValidator(cfg).validate();

20.1.8. Utiliser Ant pour la validation du Schéma

Vous pouvez appeler SchemaValidator depuis le script Ant:

<target name="schemavalidate">
    <taskdef name="schemavalidator"
        classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
        classpathref="class.path"/>
    
    <schemavalidator
        properties="hibernate.properties">
        <fileset dir="src">
            <include name="**/*.hbm.xml"/>
        </fileset>
    </schemavalidator>
</target>