Personalizar esquema con Hibernate

Lunes,12 enero, 2009 at 3:22 1 Comentario

Las anotaciones JPA junto con el plugin hbm2ddl de Hibernate, proporcionan a los desarrolladores una fácil y rápida de generar el esquema de base de datos a partir del dominio. Muchas veces debido a los restricciones de un cliente es necesario seguir unas normas para la generación de los nombres. A continuación explicaremos un conjunto de herramientas y anotaciones de las que nos podemos valer para la generación de un esquema que siga las diferentes normas para la generación del esquema.

1.- Diseñamos e implementamos las clases del dominio.

2.- Anotamos las clases del dominio con las anotaciones básicas, es decir, aquellas que son necesarias para la generación del dominio.

3.- Generamos una clase que contiene la estrategia para la generación de los nombres de las tablas y las columnas del esquema de base de datos. Para ello hemos de seguir los siguientes pasos:

a) La clase que contiene la estrategia para la generación de nombres ha de implementar la interfaz NamingStrategy, aunque en nuestro caso extenderemos de la clase EJB3NamingStrategy, que contiene una implementación base.

public class MyNamingStrategy extends EJB3NamingStrategy implements NamingStrategy

b) Sobrescribimos aquellos métodos que están relacionados con la generación del esquema de BD.

  • Métodos relacionados con la generación de los nombres de las tablas:
    /**
     * Procesado a la hora de generar los nombres de las tablas de aquellas entidades que no se le ha establecido el
     * nombre mediante la anotación Table.
     */
    @Override
    public String classToTableName(final String className) {
        ....
    }
    /**
     * Procesado a la hora de generar los nombres de las tablas de aquellas entidades que se les ha establecido el
     * nombre mediante la anotación Table de JPA.
     */
    @Override
    public String tableName(final String tableName) {
        ....
    }
    /**
     * Procesado a la hora de generar los nombres de las tablas que dan lugar a las colecciones. Procesado en los
     * ManyToMany o en los OneToMany en los que que no son mapeados por otra entidad. Sólo se procesará en el caso de
     * que no se especifique el nombre en la anotación JoinTable.
     */
    @Override
    public String collectionTableName(final String ownerEntity, final String ownerEntityTable,
            final String associatedEntity, final String associatedEntityTable, final String propertyName) {
        ....
    }
  • Métodos procesados a la hora de la generación de los nombres de las columnas:
    /**
     * Procesado a la hora de generar los nombres de las columnas de aquellos atributos que no se le ha establecido el
     * nombre mediante la anotación Column.
     */
    @Override
    public String propertyToColumnName(final String propertyName) {
        ....
    }
    /**
     * Procesado a la hora de generar los nombres de las columnas de aquellos atributos que se les ha establecido el
     * nombre mediante la anotacion Column de JPA.
     */
    @Override
    public String columnName(final String columnName) {
        ....
    }
    /**
     * Procesado a la hora de generar los nombres de las columnas que son foreingKey utilizadas en las herencias.
     */
    @Override
    public String joinKeyColumnName(final String joinedColumn, final String joinedTable) {
       ....
    }
    /**
     * Procesado a la hora de generar los nombres de las columnas que son foreingKey a otras. Este método sólo se
     * procesará en el caso de que no se indique el nombre en el JoinColumn.
     */
    @Override
    public String foreignKeyColumnName(final String propertyName, final String propertyEntityName,
            final String propertyTableName, final String referencedColumnName) {
        ....
    }

4.- Configuramos el persistence.xml para que ejecute la estrategia anteriormente indicada.

   <persistence-unit name="test">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jar-file>target/classes</jar-file>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test" />
            <property name="hibernate.connection.username" value="test" />
            <property name="hibernate.connection.password" value="test" />
            <property name="hibernate.ejb.naming_strategy" value="org.mycompany.prueba.util.MyNamingStrategy" />
            <property name="hibernate.hbm2ddl.auto" value="create" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="false" />
        </properties>
    </persistence-unit>

5.- Por defecto Hibernate autogenera la FK de forma que nunca se repiten, parecidas a FKAB1273D65CCF7AB. Estas FK no son nada intuitiva y tampoco se puede establecer una estrategia en la implementación anterior, así que mediante la anotación @ForeignKey podemos establecer el nombre que queremos para la FK. generada.

NOTA: Hay que decir que esta anotación pertenece a Hibernate y no tiene porqué existir para otras implementaciones de JPA.

    @ManyToMany
    @ForeignKey(name = "FK_USR_ACT", inverseName = "FK_ACT_USR")
    private List<Actividad> actividades;

6.- Muchas veces no nos permiten que generemos de forma automática el esquema de BD. En estos casos se suele pasar un script con las sentencias SQL que han de ejecutarse. Para ello nos podemos valer del plugin de Hibernate para maven. Esta es la configuración que hemos de añadir en nuestro POM para que mediante un package genere un fichero con el SQL correspondiente.

   <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>hibernate3-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
            <components>
                <component>
                    <name>hbm2ddl</name>
                </component>
            </components>
            <componentProperties>
                <implementation>jpaconfiguration</implementation>
                <outputfilename>create_schema.sql</outputfilename>
                <drop>false</drop>
                <create>true</create>
                <update>false</update>
                <export>false</export>
                <ejb3>true</ejb3>
            </componentProperties>
        </configuration>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>hbm2ddl</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

Adjunto un proyecto modelo, con una estrategia implementada. [Download]

Este post está basado en el post de John Ferguson.

http://www.javaworld.com/javaworld/jw-08-2008/jw-08-hibernate-annotations.html?page=1

Entrada archivada en:Bases de Datos, Hibernate, Java, Maven. Etiquetas:, , , , .

JSON ¿Qué librería elegir? Codificación en BD (MySQL y Oracle)

1 comentario Añade el tuyo

Deja un comentario

Fill in your details below or click an icon to log in:

Logo de WordPress.com

You are commenting using your WordPress.com account. Log Out / Cambiar )

Twitter picture

You are commenting using your Twitter account. Log Out / Cambiar )

Facebook photo

You are commenting using your Facebook account. Log Out / Cambiar )

Connecting to %s

Trackback este articulo  |  Suscríbete a los comentarios vía RSS Feed


Feeds

Entradas Recientes

Categorias


Seguir

Get every new post delivered to your Inbox.