Nếu bạn quan tâm, đây là một vài đoạn mã để đưa loại người dùng tùy chỉnh Hibernate vào đúng vị trí. Đầu tiên hãy mở rộng phương ngữ PostgreSQL để cho nó biết về kiểu json, nhờ Craig Ringer cho con trỏ JAVA_OBJECT:
import org.hibernate.dialect.PostgreSQL9Dialect;
import java.sql.Types;
public class JsonPostgreSQLDialect extends PostgreSQL9Dialect {
public JsonPostgreSQLDialect() {
super();
this.registerColumnType(Types.JAVA_OBJECT, "json");
}
}
Tiếp theo triển khai org.hibernate.usertype.UserType. Việc triển khai bên dưới ánh xạ các giá trị Chuỗi sang kiểu cơ sở dữ liệu json và ngược lại. Hãy nhớ rằng các chuỗi là bất biến trong Java. Một triển khai phức tạp hơn cũng có thể được sử dụng để ánh xạ các hạt Java tùy chỉnh sang JSON được lưu trữ trong cơ sở dữ liệu.
package foo;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public class StringJsonUserType implements UserType {
@Override
public int[] sqlTypes() {
return new int[] { Types.JAVA_OBJECT};
}
@Override
public Class returnedClass() {
return String.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if( x== null){
return y== null;
}
return x.equals( y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
if(rs.getString(names[0]) == null){
return null;
}
return rs.getString(names[0]);
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.OTHER);
return;
}
st.setObject(index, value, Types.OTHER);
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (String)this.deepCopy( value);
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return this.deepCopy( cached);
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
Bây giờ tất cả những gì còn lại là chú thích các thực thể. Đặt một cái gì đó như thế này tại khai báo lớp của thực thể:
@TypeDefs( {@TypeDef( name= "StringJsonObject", typeClass = StringJsonUserType.class)})
Sau đó, chú thích thuộc tính:
@Type(type = "StringJsonObject")
public String getBar() {
return bar;
}
Hibernate sẽ đảm nhận việc tạo cột với kiểu json cho bạn và xử lý ánh xạ qua lại. Đưa các thư viện bổ sung vào triển khai kiểu người dùng để ánh xạ nâng cao hơn.
Dưới đây là một dự án GitHub mẫu nhanh nếu có ai muốn chơi với nó:
https://github.com/timfulmer/hibernate-postgres-jsontype