Имах подобни изисквания, но също исках да използвам Hibernate DDL генериране и да се уверя, че SQL Server генерира уникален тип идентификатор, а също така исках да поддържам hsqldb за тестване на единици. За да използвате UUID в SQL Server, определено искате да преминете през низове, а не двоични , тъй като двоичното представяне в SQL Server е за GUID, който е различен от UUID. Вижте например различно представяне на UUID в Java Hibernate и SQL Server
Можете да създадете правилното съпоставяне и да генерирате правилния sql за SQL Server с:
@Type(type = "uuid-char")
@Column(columnDefinition="uniqueidentifier")
public UUID getUuid()
И това просто работи както е, но за съжаление няма начин в Hibernate да има различни дефиниции на колони за различни бази данни, така че това ще се провали на нещо различно от SQL Server.
Така че, трябва да изминете дългия път. Това е всичко за Hibernate 4.3:
- Регистрирайте нов тип GUID sql в заменен SQLServerDialect и използвайте този диалект вместо основния
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)" );
}
}
- Създайте обвивка UUIDCustomType, която се държи подобно на вградения UUIDCharType, но делегира в зависимост от типа база данни. Трябва да извикате init(databaseType) преди Конфигурация за хибернация. Може би персонализираният диалект би могъл да го направи, но аз наричам това при стартирането на моето 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, но работи чудесно за hsqldb и sql сървър на Hibernate 4.3.