同様の要件がありましたが、Hibernate DDL生成を使用して、SQL Serverが一意の識別子タイプを生成することを確認し、ユニットテスト用のhsqldbもサポートしたいと考えていました。SQLServerでUUIDを使用するには、バイナリではなく文字列を使用する必要があります。 、SQL Serverのバイナリ表現は、UUIDとは異なるGUID用であるため。たとえば、JavaHibernateとSQLServerでのUUIDの異なる表現を参照してください
次のコマンドを使用して、正しいマッピングを作成し、SQLServerの正しいSQLを生成できます。
@Type(type = "uuid-char")
@Column(columnDefinition="uniqueidentifier")
public UUID getUuid()
これはそのまま機能しますが、残念ながら、Hibernateにはデータベースごとに異なるcolumnDefinitionsを設定する方法がないため、SQLServer以外では失敗します。
だから、あなたは長い道のりを歩かなければなりません。これはすべてHibernate4.3の場合です:
- オーバーライドされたSQLServerDialectに新しいGUIDSQLタイプを登録し、ベースの方言の代わりにこの方言を使用します
public class SQLServer2008UnicodeDialect extends SQLServer2008Dialect
{
public SQLServer2008UnicodeDialect()
{
// the const is from the MS JDBC driver, the value is -145
registerColumnType( microsoft.sql.Types.GUID, "uniqueidentifier" );
// etc. Bonus hint: I also remap all the varchar types to nvarchar while I'm at it, like so:
registerColumnType( Types.CLOB, "nvarchar(MAX)" );
registerColumnType( Types.LONGVARCHAR, "nvarchar(MAX)" );
registerColumnType( Types.LONGNVARCHAR, "nvarchar(MAX)" );
registerColumnType( Types.VARCHAR, "nvarchar(MAX)" );
registerColumnType( Types.VARCHAR, 8000, "nvarchar($l)" );
}
}
- 組み込みのUUIDCharTypeと同様に動作するが、データベースの種類に応じて委任するラッパーUUIDCustomTypeを作成します。 前にinit(databaseType)を呼び出す必要があります Hibernate構成。カスタム方言でそれができるかもしれませんが、Springアプリのスタートアップでこれを呼び出します。
DatabaseTypeは、システム構成に基づいて設定された列挙型であり、方言クラスや文字列などを使用して好みに合わせて変更します。
これは、https://zorq.net/b/2012/04/21/switching-hibernates-uuid-type-mapping-per-database/
で説明されているもののバリエーションです。public enum DatabaseType
{
hsqldb,
sqlserver,
mysql,
postgres
}
public class UUIDCustomType extends AbstractSingleColumnStandardBasicType<UUID> implements LiteralType<UUID>
{
private static final long serialVersionUID = 1L;
private static SqlTypeDescriptor SQL_DESCRIPTOR;
private static JavaTypeDescriptor<UUID> TYPE_DESCRIPTOR;
public static void init( DatabaseType databaseType )
{
if ( databaseType == DatabaseType.sqlserver )
{
SQL_DESCRIPTOR = SqlServerUUIDTypeDescriptor.INSTANCE;
}
else if ( databaseType == DatabaseType.postgres )
{
SQL_DESCRIPTOR = PostgresUUIDType.PostgresUUIDSqlTypeDescriptor.INSTANCE;
}
else
{
SQL_DESCRIPTOR = VarcharTypeDescriptor.INSTANCE;
}
TYPE_DESCRIPTOR = UUIDTypeDescriptor.INSTANCE;
}
public UUIDCustomType()
{
super( SQL_DESCRIPTOR, TYPE_DESCRIPTOR );
}
@Override
public String getName()
{
return "uuid-custom";
}
@Override
public String objectToSQLString( UUID value, Dialect dialect ) throws Exception
{
return StringType.INSTANCE.objectToSQLString( value.toString(), dialect );
}
public static class SqlServerUUIDTypeDescriptor extends VarcharTypeDescriptor
{
private static final long serialVersionUID = 1L;
public static final SqlServerUUIDTypeDescriptor INSTANCE = new SqlServerUUIDTypeDescriptor();
public SqlServerUUIDTypeDescriptor()
{
}
@Override
public int getSqlType()
{
return microsoft.sql.Types.GUID;
}
}
}
- Hibernateが取得する場所にカスタムタイプを登録します(すべてのエンティティに共通の基本クラスがあります)。 defaultForType =UUID.classを使用して登録し、すべてのUUIDがそれを使用するようにします。つまり、UUIDプロパティに注釈を付ける必要はまったくありません。
@TypeDefs( {
@TypeDef( name = "uuid-custom", typeClass = UUIDCustomType.class, defaultForType = UUID.class )
} )
public class BaseEntityWithId {
警告:実際にはpostgresでテストされていませんが、Hibernate4.3上のhsqldbおよびsqlサーバーでうまく機能しています。