Zoeken…


Een aangepaste ImplicitNamingStrategy maken en gebruiken

Door een aangepaste ImplicitNamingStrategy kunt u aanpassen hoe Hibernate namen toewijst aan niet-expliciet benoemde Entity , waaronder buitenlandse sleutels, unieke sleutels, identificatiekolommen, basiskolommen en meer.

Hibernate genereert bijvoorbeeld standaard buitenlandse sleutels die zijn gehasht en die lijken op:

FKe6hidh4u0qh8y1ijy59s2ee6m

Hoewel dit vaak geen probleem is, wilt u misschien dat de naam meer beschrijvend was, zoals:

FK_asset_tenant

Dit kan eenvoudig worden gedaan met een aangepaste ImplicitNamingStrategy .

Dit voorbeeld breidt de ImplicitNamingStrategyJpaCompliantImpl , maar u kunt er ook voor kiezen om ImplicitNamingStrategy te implementeren als u dat wenst.

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());
    }

}

Om Hibernate te vertellen welke ImplicitNamingStrategy moet worden gebruikt, definieert u de eigenschap hibernate.implicit_naming_strategy in uw bestand persistence.xml of hibernate.cfg.xml zoals hieronder:

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

Of u kunt de eigenschap in het bestand hibernate.properties als volgt opgeven:

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

In dit voorbeeld krijgen alle buitenlandse sleutels die geen expliciet gedefinieerde name , hun naam nu van de CustomNamingStrategy .

Aangepaste fysieke naamstrategie

Bij het toewijzen van onze entiteiten aan databasetabelnamen vertrouwen we op een @Table annotatie. Maar als we een naamgevingsconventie hebben voor onze databasetabelnamen, kunnen we een aangepaste fysieke naamgevingsstrategie implementeren om de slaapstand te vertellen om tabelnamen te berekenen op basis van de namen van de entiteiten, zonder die namen expliciet te vermelden met @Table annotatie. Hetzelfde geldt voor het toewijzen van attributen en kolommen.

Onze entiteitsnaam is bijvoorbeeld:

ApplicationEventLog

En onze tabelnaam is:

application_event_log

Onze fysieke naamgevingsstrategie moet worden omgezet van entiteitsnamen die kameelgeval zijn naar onze DB-tabelnamen die slanggeval zijn. We kunnen dit bereiken door PhysicalNamingStrategyStandardImpl hibernate uit te breiden:

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);
    }
}

We hebben toPhysicalColumnName op het standaardgedrag van methoden voor toPhysicalTableName en toPhysicalColumnName om onze db-naamgevingsconventie toe te passen.

Om onze aangepaste implementatie te gebruiken, moeten we de eigenschap hibernate.physical_naming_strategy definiëren en deze de naam geven van onze klasse PhysicalNamingStrategyImpl .

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

Op deze manier kunnen we onze code van annotaties bij @Table en @Column verlichten, dus onze entiteitsklasse:

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

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

wordt correct toegewezen aan db-tabel:

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

Zoals te zien in het bovenstaande voorbeeld, kunnen we de naam van het DB-object nog steeds expliciet vermelden als het om een of andere reden niet in overeenstemming is met onze algemene naamgevingsconventie: @Column(name="finish_dtl")



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow