hibernate
Estrategia de nomenclatura personalizada
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")