Buscar..


Creación y uso de una ImplicitNamingStrategy personalizada

La creación de una ImplicitNamingStrategy personalizada le permite modificar la forma en que Hibernate asignará nombres a los atributos de Entity no explícitamente nombrados, incluidas las claves externas, las claves únicas, las columnas identificadoras, las columnas básicas y mucho más.

Por ejemplo, de forma predeterminada, Hibernate generará claves foráneas que están en hash y son similares a:

FKe6hidh4u0qh8y1ijy59s2ee6m

Si bien esto no suele ser un problema, es posible que desee que el nombre sea más descriptivo, como:

FK_asset_tenant

Esto se puede hacer fácilmente con un ImplicitNamingStrategy personalizado.

Este ejemplo amplía ImplicitNamingStrategyJpaCompliantImpl , sin embargo, puede elegir implementar ImplicitNamingStrategy si lo desea.

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitForeignKeyNameSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;

public class CustomNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl {

    @Override
    public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {
        return toIdentifier("FK_" + source.getTableName().getCanonicalName() + "_" + source.getReferencedTableName().getCanonicalName(), source.getBuildingContext());
    }

}

Para indicar a Hibernate qué ImplicitNamingStrategy debe usar, defina la propiedad hibernate.implicit_naming_strategy en su archivo persistence.xml o hibernate.cfg.xml como se muestra a continuación:

<property name="hibernate.implicit_naming_strategy"
                  value="com.example.foo.bar.CustomNamingStrategy"/>

O puede especificar la propiedad en el archivo hibernate.properties la siguiente manera:

hibernate.implicit_naming_strategy=com.example.foo.bar.CustomNamingStrategy

En este ejemplo, todas las Claves foráneas que no tienen un name definido explícitamente ahora obtendrán su nombre de CustomNamingStrategy .

Estrategia de nomenclatura física personalizada

Al asignar nuestras entidades a nombres de tablas de bases de datos, nos basamos en una anotación de @Table . Pero si tenemos una convención de nomenclatura para los nombres de nuestras tablas de la base de datos, podemos implementar una estrategia de denominación física personalizada para indicar a Hibernate que calcule los nombres de las tablas basándose en los nombres de las entidades, sin indicar explícitamente esos nombres con la anotación @Table . Lo mismo ocurre con la asignación de atributos y columnas.

Por ejemplo, el nombre de nuestra entidad es:

ApplicationEventLog

Y nuestro nombre de mesa es:

application_event_log

Nuestra estrategia de nomenclatura física necesita convertir los nombres de entidades que son casos de camellos a los nombres de nuestras tablas db que son casos de serpientes. Podemos lograr esto extendiendo PhysicalNamingStrategyStandardImpl de hibernate:

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl {

    private static final long serialVersionUID = 1L;
    public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }

    protected static String addUnderscores(String name) {
        final StringBuilder buf = new StringBuilder(name);
        for (int i = 1; i < buf.length() - 1; i++) {
            if (Character.isLowerCase(buf.charAt(i - 1)) &&
                    Character.isUpperCase(buf.charAt(i)) &&
                    Character.isLowerCase(buf.charAt(i + 1))) {
                buf.insert(i++, '_');
            }
        }
        return buf.toString().toLowerCase(Locale.ROOT);
    }
}

Estamos anulando el comportamiento predeterminado de los métodos toPhysicalTableName y toPhysicalColumnName para aplicar nuestra convención de nomenclatura de db.

Para utilizar nuestra implementación personalizada, necesitamos definir la propiedad hibernate.physical_naming_strategy y darle el nombre de nuestra clase PhysicalNamingStrategyImpl .

hibernate.physical_naming_strategy=com.example.foo.bar.PhysicalNamingStrategyImpl

De esta manera podemos aliviar nuestro código de las anotaciones @Table y @Column , por lo que nuestra clase de entidad:

@Entity
public class ApplicationEventLog {
    private Date startTimestamp;
    private String logUser;
    private Integer eventSuccess;

    @Column(name="finish_dtl")
    private String finishDetails;
}

será correctamente asignado a la tabla db:

CREATE TABLE application_event_log (
  ...
  start_timestamp timestamp,
  log_user varchar(255),
  event_success int(11),
  finish_dtl varchar(2000),
  ...
)

Como se vio en el ejemplo anterior, aún podemos indicar explícitamente el nombre del objeto db si no lo está, por alguna razón, de acuerdo con nuestra convención general de nomenclatura: @Column(name="finish_dtl")



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow