Suche…


Erstellen und Verwenden eines benutzerdefinierten ImplicitNamingStrategy

Durch das Erstellen eines benutzerdefinierten ImplicitNamingStrategy können Sie optimieren, wie Hibernate nicht explizit benannten Entity , einschließlich Fremdschlüsseln, eindeutigen Schlüsseln, Bezeichnerspalten, Basisspalten usw., Namen zuweist.

Beispielsweise generiert Hibernate standardmäßig Fremdschlüssel, die gehasht werden und ähnlich aussehen:

FKe6hidh4u0qh8y1ijy59s2ee6m

Obwohl dies häufig kein Problem ist, möchten Sie vielleicht, dass der Name aussagekräftiger ist, z. B .:

FK_asset_tenant

Dies kann leicht mit einer benutzerdefinierten ImplicitNamingStrategy .

In diesem Beispiel wird ImplicitNamingStrategyJpaCompliantImpl . Sie können jedoch auch ImplicitNamingStrategy implementieren, wenn Sie möchten.

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

}

Um Hibernate mitzuteilen, welche ImplicitNamingStrategy verwendet werden soll, definieren Sie die Eigenschaft hibernate.implicit_naming_strategy in Ihrer Datei persistence.xml oder hibernate.cfg.xml wie folgt:

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

Oder Sie können die Eigenschaft in der Datei hibernate.properties wie folgt angeben:

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

In diesem Beispiel erhalten alle Fremdschlüssel, die keinen explizit definierten name haben, jetzt ihren Namen von CustomNamingStrategy .

Benutzerdefinierte physikalische Benennungsstrategie

Bei der Zuordnung unserer Entitäten zu Namen von Datenbanktabellen verlassen wir uns auf eine @Table Annotation. Wenn wir jedoch eine Namenskonvention für die Namen der Datenbanktabellen haben, können wir eine benutzerdefinierte Strategie für die physische Benennung implementieren, um dem Hibernate mitzuteilen, dass Tabellennamen basierend auf den Namen der Entitäten berechnet werden, ohne diese Namen explizit mit der @Table Annotation @Table . Gleiches gilt für die Zuordnung von Attributen und Spalten.

Unser Entitätsname lautet beispielsweise:

ApplicationEventLog

Und unser Tabellenname lautet:

application_event_log

Unsere physikalische Benennungsstrategie muss von Entitätsnamen, bei denen es sich um Kamel-Großbuchstaben handelt, in unsere Db-Tabellennamen, bei denen es sich um Schlangen handelt, konvertieren. Wir können dies erreichen, indem Sie PhysicalNamingStrategyStandardImpl von hibernate erweitern:

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

Wir überschreiben das Standardverhalten der Methoden toPhysicalTableName und toPhysicalColumnName , um unsere toPhysicalColumnName anzuwenden.

Um unsere benutzerdefinierte Implementierung verwenden zu können, müssen wir die Eigenschaft hibernate.physical_naming_strategy definieren und der Klasse PhysicalNamingStrategyImpl den Namen geben.

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

Auf diese Weise können wir unseren Code aus den @Table und @Column Annotationen @Column , so dass unsere Entitätsklasse:

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

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

wird korrekt auf db table abgebildet:

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

Wie im obigen Beispiel gezeigt, können wir den Namen des db-Objekts immer noch explizit @Column(name="finish_dtl") wenn es aus irgendeinem Grund nicht unserer allgemeinen Namenskonvention entspricht: @Column(name="finish_dtl")



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow