虽然,我很晚才回答这个问题,但我设法以一种非常简单的方式实现了这一点,而且工作如此顺利 -
我创建了一个自定义的 Hibernate 类型,它实现UserType
:
package com.wizpanda.hibernate
import groovy.transform.CompileStatic
import org.grails.web.json.JSONObject
import org.hibernate.HibernateException
import org.hibernate.engine.spi.SessionImplementor
import org.hibernate.usertype.UserType
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.SQLException
import java.sql.Types
/**
* An implementation of {@link org.grails.web.json.JSONObject} column using Hibernate custom types.
* https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#_custom_type
* https://docs.jboss.org/hibernate/orm/current/javadocs/org/hibernate/usertype/UserType.html
*
* @author Shashank Agrawal
*/
@CompileStatic
class JSONObjectFooType implements UserType {
@Override
int[] sqlTypes() {
return [Types.OTHER] as int[]
}
//@SuppressWarnings("rawtypes")
@Override
Class returnedClass() {
return JSONObject.class
}
@Override
boolean equals(Object x, Object y) throws HibernateException {
return x && x.equals(y)
}
@Override
int hashCode(Object x) throws HibernateException {
return x.hashCode()
}
@Override
Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
String value = rs.getString(names[0])
if (!value) {
return null
}
return new JSONObject(value)
}
@Override
void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
String valueToPersist
if (value) {
if (value instanceof JSONObject) {
valueToPersist = value.toString()
} else if (value instanceof String) {
valueToPersist = new JSONObject(value).toString(0)
} else {
throw new HibernateException("Unknown type received for JSONObject based column")
}
}
st.setObject(index, valueToPersist, Types.OTHER)
}
@Override
Object deepCopy(Object value) throws HibernateException {
if (!value) {
return null
}
if (value instanceof JSONObject) {
return new JSONObject(value.toString(0))
}
return value
}
@Override
boolean isMutable() {
return false
}
@Override
Serializable disassemble(Object value) throws HibernateException {
if (value instanceof JSONObject) {
return value?.toString(0)
}
return value?.toString()
}
@Override
Object assemble(Serializable cached, Object owner) throws HibernateException {
if (!cached) {
return null
}
return new JSONObject(cached.toString())
}
@Override
Object replace(Object original, Object target, Object owner) throws HibernateException {
return deepCopy(original)
}
}
我使用org.grails.web.json.JSONObject
它是因为这是 Grails 内部的,您可以使用其他类似org.json.JSONObject
或 Groovy json 并替换上面的出现。
现在,在您的域类中简单地使用它-
class User {
String email
String name
JSONObject settings
static mapping = {
settings type: JSONObjectFooType, sqlType: "text"
}
}
合十!