Поиск…


Создание и использование пользовательской ImplicitNamingStrategy

Создание пользовательской ImplicitNamingStrategy позволяет вам настроить, как Hibernate присваивает имена неявным образом атрибутам Entity , включая внешние ключи, уникальные ключи, столбцы идентификаторов, базовые столбцы и т. Д.

Например, по умолчанию Hibernate генерирует внешние ключи, которые хэшируются и выглядят похожими на:

FKe6hidh4u0qh8y1ijy59s2ee6m

Хотя это часто не является проблемой, вы можете пожелать, чтобы имя было более наглядным, например:

FK_asset_tenant

Это легко сделать с помощью пользовательской ImplicitNamingStrategy .

Этот пример расширяет ImplicitNamingStrategyJpaCompliantImpl , однако вы можете выбрать 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());
    }

}

Для того, чтобы сказать , спящий режим , который ImplicitNamingStrategy использовать, определить hibernate.implicit_naming_strategy свойство в ваших persistence.xml или hibernate.cfg.xml файл , как показано ниже:

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

Или вы можете указать свойство в файле hibernate.properties как показано ниже:

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

В этом примере все внешние ключи, которые не имеют явно определенного name , теперь получат свое имя из CustomNamingStrategy .

Пользовательская стратегия физического наименования

При сопоставлении наших объектов с именами таблиц базы данных мы полагаемся на аннотацию @Table . Но если у нас есть соглашение об именах для имен таблиц базы данных, мы можем реализовать пользовательскую стратегию физического именования, чтобы сообщить hibernate рассчитать имена таблиц на основе имен сущностей без явного указания этих имен с @Table аннотации @Table . То же самое касается отображения атрибутов и столбцов.

Например, название нашей организации:

ApplicationEventLog

И наше имя таблицы:

application_event_log

Наша стратегия физического именования должна конвертироваться из имен сущностей, которые являются верблюжьим футляром, к нашим именам таблиц db, которые представляют собой случай змей. Мы можем добиться этого, расширив PhysicalNamingStrategyStandardImpl Hibernate's PhysicalNamingStrategyStandardImpl :

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

Мы переопределяем поведение по умолчанию методов toPhysicalTableName и toPhysicalColumnName для применения нашего соглашения об именах db.

Чтобы использовать нашу пользовательскую реализацию, нам нужно определить свойство hibernate.physical_naming_strategy и присвоить ей имя нашего класса PhysicalNamingStrategyImpl .

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

Таким образом, мы можем облегчить наш код из @Table и @Column аннотаций, поэтому наш класс сущностей:

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

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

будет правильно отображаться в таблице db:

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

Как видно из приведенного выше примера, мы можем явно указать имя объекта db, если по какой-либо причине оно не соответствует нашему общему соглашению об именах: @Column(name="finish_dtl")



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow