Hibernateデータベースの方言の小談


システムが複数のデータベースで動作したり、複数のデータベースを同時に使用したりする可能性がある場合は、Hibernateを使用することで多くの便利さをもたらし、Hibernateに接触している多くの人が知っていることを信じたいと思っています.Hibernate下位層はdialectパッケージによって様々なデータベースの違いを抽象化する.Dialectクラスでは各データベースと同じものが実装され、異なるデータベースにはそのクラスの拡張実装があり、最終的にはDialectFactoryによってどのクラスを作成するかが決定されます.通常はhibernateを指定します.dialectプロパティ.このプロパティに対応するクラスを直接作成します.この属性を指定していない場合は、Hibernate自身が適切な方言を選択することを決定します.DialectFactoryでは各種データベースに対応する方言のMapを初期化し,データベース製品名をkey,方言のパッケージオブジェクトをvalueとする.Hibernate自動方言選択の場合、JDBCのDatabaseMetadataでデータベースの製品名を取得し、名前に応じて対応する方言を取得します.DialectFactoryにおけるこのMapの初期化の一部のコードは以下の通りである.
// TODO : this is the stuff it'd be nice to move to a properties file or some other easily user-editable place
	private static final Map MAPPERS = new HashMap();
	static {
		// detectors...
		MAPPERS.put( "HSQL Database Engine", new VersionInsensitiveMapper( "org.hibernate.dialect.HSQLDialect" ) );
		MAPPERS.put( "H2", new VersionInsensitiveMapper( "org.hibernate.dialect.H2Dialect" ) );
		MAPPERS.put( "MySQL", new VersionInsensitiveMapper( "org.hibernate.dialect.MySQLDialect" ) );
		MAPPERS.put( "PostgreSQL", new VersionInsensitiveMapper( "org.hibernate.dialect.PostgreSQLDialect" ) );
		MAPPERS.put( "Apache Derby", new VersionInsensitiveMapper( "org.hibernate.dialect.DerbyDialect" ) );
...



本来、このような自動選択の方式は、私たちに便利さをもたらしますが、残念ながら、以上のコードの注釈から分かるように、現在のこの部分の初期化はハードコーディングによって行われており、後のバージョンでのみプロファイルや他のユーザーでコンパイルしやすい場所に移動することができます.そうしないと、Hibernateが自動的に選択できるように構成を簡単に追加できます.常に使用しているデータベースドライバが取得するデータベース製品名は、上記のハードコーディングとは異なりますので、最終的には自分でデータベース方言を構成する必要があります.
我々のシステムでは、いくつかのデータソースが使用されているため、常に異なるタイプのデータベースに対応しており、データソースはコンテナによって提供されており、最初の導入時にデータベースタイプが変わったため、対応するデータベースの方言を修正することを忘れてしまい、問題が発生し、実施者に多くの不便をもたらしています.しかし、現在では、上記のハードコーディングと同じデータベース製品名をさまざまなデータベースに提供するドライバを除いて、私たちは自分で手を出すしかありません.