Grails和hibernate通常會以字符串形式處理UUID。使用二進制UUID可能需要多一點工作。聲明id
的類型爲UUID
並提供一個hibernate用戶類型以將其序列化爲一個字節數組。您還需要告訴Grails用於UUID的SQL類型。例如:
class Person {
static mapping = {
id generator:'assigned', type: UUIDUserType, sqlType: 'varbinary(16)'
}
UUID id
def beforeInsert = {
if (!id) {
id = UUID.randomUUID()
}
}
}
爲UUID的用戶類型是:
import java.nio.ByteBuffer
import java.nio.LongBuffer
import java.sql.ResultSet
import java.sql.PreparedStatement
import java.sql.Types
import org.hibernate.usertype.UserType
public class UUIDUserType implements UserType {
int[] sqlTypes() { [Types.VARBINARY] as int [] }
Class returnedClass() { UUID }
Object nullSafeGet(ResultSet resultSet, String[] names, owner) {
byte[] value = resultSet.getBytes(names[0])
return value ? bytesToUuid(value) : null
}
void nullSafeSet(PreparedStatement statement, value, int index) {
if (value == null) {
statement.setNull(index, Types.VARBINARY)
} else {
statement.setBytes(index, uuidToBytes(value))
}
}
boolean equals(x, y) { x == y }
int hashCode(x) { x.hashCode() }
Object deepCopy(value) { value }
boolean isMutable() { false }
Serializable disassemble(value) { value }
Object assemble(Serializable cached, owner) { cached }
def replace(original, target, owner) { original }
static byte[] uuidToBytes(uuid) {
def bytes = new byte[16];
ByteBuffer.wrap(bytes).asLongBuffer().with {
put(0, uuid.mostSignificantBits)
put(1, uuid.leastSignificantBits)
}
bytes
}
static UUID bytesToUuid(bytes) {
ByteBuffer.wrap(bytes).asLongBuffer().with {
new UUID(get(0), get(1))
}
}
}
這並不在MySQL工作:2011-02-27 10:18:33818 [主要] ERROR hbm2ddl.SchemaExport - 失敗:創建表人(id tinyblob非null,版本bigint不爲null,主鍵(id)) 2011-02-27 10:18:33,819 [main] ERROR hbm2ddl.SchemaExport - 在密鑰規範中使用的BLOB/TEXT列'id'密鑰長度 2011-02-27 10:18:36,702 [main] ERROR util.JDBCExceptionReporter - 表'testuuid.person'不存在 – imrank1 2011-02-27 15:20:35
糟糕,你是對的。我假定grails自動處理非字符串UUID,但事實證明它不是。我已經用修正更新了答案。 – ataylor 2011-02-27 20:55:07
ahh是一個自定義的usertype。我會認爲Grails或者Hibernate會爲我們處理這個問題。總的來說,解決方案工作..但是,當使用varbinary(16)作爲實體的主鍵時,grails/hibernate對於belongsTo關係有問題。唯一的解決方案似乎是首先手動創建數據庫方案。 – imrank1 2011-03-01 12:26:32