Tôi có các yêu cầu tương tự, nhưng tôi cũng muốn sử dụng tạo DDL Hibernate và đảm bảo rằng SQL Server đã tạo một loại mã bảo mật duy nhất và cũng muốn hỗ trợ hsqldb để kiểm tra đơn vị. , vì biểu diễn nhị phân trong SQL Server dành cho GUID khác với UUID. Xem ví dụ về cách biểu diễn UUID khác nhau trong Java Hibernate và SQL Server
Bạn có thể tạo ánh xạ chính xác và tạo sql chính xác cho SQL Server bằng:
@Type(type = "uuid-char")
@Column(columnDefinition="uniqueidentifier")
public UUID getUuid()
Và điều này vẫn hoạt động như vậy, nhưng tiếc là không có cách nào trong Hibernate để có các Định nghĩa cột khác nhau cho các cơ sở dữ liệu khác nhau, vì vậy điều này sẽ không thành công trên bất kỳ thứ gì khác ngoài SQL Server.
Vì vậy, bạn phải đi một chặng đường dài. Đây là tất cả cho Hibernate 4.3:
- Đăng ký kiểu sql GUID mới trong SQLServerDialect bị ghi đè và sử dụng phương ngữ này thay vì phương ngữ cơ sở
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)" );
}
}
- Tạo một trình bao bọc UUIDCustomType hoạt động tương tự như UUIDCharType được tích hợp sẵn nhưng ủy quyền tùy thuộc vào loại cơ sở dữ liệu. Bạn cần gọi init (databaseType) trước Cấu hình ngủ đông. Có thể phương ngữ tùy chỉnh có thể làm được điều đó, nhưng tôi gọi điều này khi khởi động ứng dụng Spring của mình.
DatabaseType là một enum mà tôi đã có được đặt dựa trên cấu hình hệ thống, hãy sửa đổi nó cho phù hợp bằng cách sử dụng lớp phương ngữ hoặc chuỗi hoặc bất cứ thứ gì.
Đây là một biến thể của những gì được mô tả tại 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;
}
}
}
- Đăng ký loại tùy chỉnh ở một vị trí mà Hibernate sẽ chọn (Tôi có một lớp cơ sở chung cho tất cả các thực thể). Tôi đăng ký nó bằng cách sử dụng defaultForType =UUID.class để tất cả các UUID đều sử dụng nó, điều đó có nghĩa là tôi không cần phải chú thích các thuộc tính của UUID.
@TypeDefs( {
@TypeDef( name = "uuid-custom", typeClass = UUIDCustomType.class, defaultForType = UUID.class )
} )
public class BaseEntityWithId {
Lưu ý:không thực sự được thử nghiệm với postgres, nhưng hoạt động tốt cho máy chủ hsqldb và sql trên Hibernate 4.3.