grails using uuid as id and mapping to to binary column
I want to use a UUID for the id for my domain objects. The idea is that the uuid could be provided by a client and if not a UUID will be generated. I have the definition as like so : 开发者_开发问答:
class Person {
static mapping = {
id generator:'assigned'
}
String id
def getUUID ={
return java.util.UUID.randomUUID().toString();
}
transient beforeInsert = {
if ( id == null || id.equals(""))
id = getUUID();
}
}
Now assuming I strip the dashes out that are included in the java UUID or client provided UUID I'd like this to be stored in a binary field in my MySQL database. And also on retrieval have the correct format to send back.
How can I accomplish that? Thoughts on a better way to do this?
Grails and hibernate usually handle UUIDs in their string form. Using binary UUIDs is possible with a little more work. Declare id
to be of type UUID
and provide a hibernate user type to serialize it as an array of bytes. You'll also need to tell grails what SQL type to use for the UUID. For example:
class Person {
static mapping = {
id generator:'assigned', type: UUIDUserType, sqlType: 'varbinary(16)'
}
UUID id
def beforeInsert = {
if (!id) {
id = UUID.randomUUID()
}
}
}
The user type for UUID is:
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))
}
}
}
精彩评论