サーチ…


カスタム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に指示するには、以下のように、 persistence.xmlまたはhibernate.cfg.xmlファイルのhibernate.implicit_naming_strategyプロパティを定義します。

<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アノテーションに依存します。しかし、データベーステーブル名の命名規則を持っている場合は、 @Tableアノテーションを明示的に記述することなく、エンティティの名前に基づいてテーブル名を計算するようにhibernateに指示するために、カスタムの物理命名戦略を実装できます。属性と列のマッピングも同じです。

たとえば、エンティティ名は次のとおりです。

ApplicationEventLog

私たちのテーブル名は:

application_event_log

私たちの物理的な命名戦略は、キャメルケースのエンティティ名からスネークケースのdbテーブル名に変換する必要があります。これを実現するには、Hibernateの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);
    }
}

私たちは、メソッドのデフォルトの動作をオーバーライドしているtoPhysicalTableNametoPhysicalColumnName私たちデシベルの命名規則を適用します。

カスタム実装を使用するには、 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")することができます: @Column(name="finish_dtl")



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow