hibernate
Strategia di denominazione personalizzata
Ricerca…
Creazione e utilizzo di una piattaforma ImplicitNaming personalizzata
La creazione di una ImplicitNamingStrategy
personalizzata consente di modificare il modo in cui Hibernate assegnerà i nomi agli attributi di Entity
non esplicitamente denominati, incluse chiavi esterne, chiavi univoche, colonne identificatore, colonne di base e altro.
Ad esempio, per impostazione predefinita, Hibernate genererà chiavi esterne che sono hash e assomigliano a:
FKe6hidh4u0qh8y1ijy59s2ee6m
Anche se questo spesso non è un problema, potresti desiderare che il nome fosse più descrittivo, come ad esempio:
FK_asset_tenant
Questo può essere fatto facilmente con una ImplicitNamingStrategy
personalizzata.
Questo esempio estende ImplicitNamingStrategyJpaCompliantImpl
, tuttavia, se lo desideri, puoi scegliere di implementare ImplicitNamingStrategy
.
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());
}
}
Per indicare a Hibernate quale ImplicitNamingStrategy
utilizzare, definire la proprietà hibernate.implicit_naming_strategy
nel file persistence.xml
o hibernate.cfg.xml
come di seguito:
<property name="hibernate.implicit_naming_strategy"
value="com.example.foo.bar.CustomNamingStrategy"/>
Oppure puoi specificare la proprietà nel file hibernate.properties
come di seguito:
hibernate.implicit_naming_strategy=com.example.foo.bar.CustomNamingStrategy
In questo esempio, tutte le chiavi CustomNamingStrategy
che non hanno un name
definito esplicitamente riceveranno il loro nome da CustomNamingStrategy
.
Strategia di denominazione fisica personalizzata
Quando mappiamo le nostre entità ai nomi delle tabelle del database, ci basiamo su un'annotazione @Table
. Ma se abbiamo una convenzione di denominazione per i nostri nomi di tabelle di database, possiamo implementare una strategia di denominazione fisica personalizzata per dire in ibernato di calcolare i nomi delle tabelle in base ai nomi delle entità, senza specificare esplicitamente tali nomi con @Table
annotazione @Table
. Lo stesso vale per gli attributi e la mappatura delle colonne.
Ad esempio, il nome della nostra entità è:
ApplicationEventLog
E il nostro nome della tabella è:
application_event_log
La nostra strategia di denominazione fisica ha bisogno di convertire da nomi di entità che sono case cammello ai nostri nomi di tabelle db che sono caso di serpente. Possiamo raggiungere questo obiettivo estendendo il PhysicalNamingStrategyStandardImpl
di 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);
}
}
Stiamo sovrascrivendo il comportamento predefinito dei metodi toPhysicalTableName
e toPhysicalColumnName
per applicare la nostra convenzione di denominazione toPhysicalColumnName
.
Per utilizzare la nostra implementazione personalizzata dobbiamo definire la proprietà hibernate.physical_naming_strategy
e dargli il nome della nostra classe PhysicalNamingStrategyImpl
.
hibernate.physical_naming_strategy=com.example.foo.bar.PhysicalNamingStrategyImpl
In questo modo possiamo alleviare il nostro codice dalle annotazioni @Table
e @Column
, quindi la nostra classe di entità:
@Entity
public class ApplicationEventLog {
private Date startTimestamp;
private String logUser;
private Integer eventSuccess;
@Column(name="finish_dtl")
private String finishDetails;
}
sarà correttamente mappato alla tabella db:
CREATE TABLE application_event_log (
...
start_timestamp timestamp,
log_user varchar(255),
event_success int(11),
finish_dtl varchar(2000),
...
)
Come visto nell'esempio sopra, possiamo ancora dichiarare esplicitamente il nome dell'oggetto db se non lo è, per qualche ragione, secondo la nostra convenzione di denominazione generale: @Column(name="finish_dtl")