(De)将JPA中的实体嵌入值对象序列化为JSON

时间:2015-10-04 10:41:20

标签: java json jpa serialization

我有一个带有值对象LatLng position的实体,它应该嵌入到一个字段中。我的LatLng类是Serializable,默认情况下使用的是BLOB,它通过Object*Stream序列化,到目前为止。

我的要求是能够操纵那些值对象,例如在phpmyadmin中,BLOB不适合,也不是人类可读的格式。

因此我想使用JSON,但我找不到任何方法来解决我的问题。

有什么想法吗? 谢谢!

//编辑2:

由于我无法使用转换器,因此我已经进入了更深层次的休眠状态。我已经实施了新的UserType

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.StringType;
import org.hibernate.usertype.UserType;
import org.springframework.util.ObjectUtils;

public class JsonSerializedUserType implements UserType {

    private final Class<?> returnedClass;

    public JsonSerializedUserType(Class<?> returnedClass) {
        this.returnedClass = returnedClass;
    }

    @Override
    public int[] sqlTypes() {
        return new int[]{
            Types.CLOB
        };
    }

    @Override
    @SuppressWarnings("rawtypes")
    public Class returnedClass() {
        return returnedClass;
    }

    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        return ObjectUtils.nullSafeEquals(x, y);
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        return ObjectUtils.nullSafeHashCode(x);
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
            throws HibernateException, SQLException {

        final String json = (String) StringType.INSTANCE.nullSafeGet(rs, names, session, owner);
        return fromJson(json);
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
            throws HibernateException, SQLException {

        StringType.INSTANCE.nullSafeSet(st, toJson(value), index, session);
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {

        try {
            // first try copy constructor
            final Class<?> objClass = value.getClass();
            final Constructor<?> ctor = objClass.getConstructor(objClass);

            return ctor.newInstance(value);
        } catch (
                NoSuchMethodException
                | SecurityException
                | InvocationTargetException
                | IllegalAccessException
                | InstantiationException
                e
        ) {

        }

        // we expect object to be serializable via gson thus this is should be a deep copy
        return fromJson(toJson(value));
    }

    @Override
    public boolean isMutable() {
        return true;
    }

    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return toJson(value);
    }

    @Override
    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        assert cached instanceof String;
        return fromJson((String)cached);
    }

    @Override
    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return deepCopy(original);
    }

    private String toJson(Object object) {
        return GsonProvider.get().toJson(object);
    }

    private Object fromJson(String json) {
        return GsonProvider.get().fromJson(json, returnedClass);
    }

}

我在春季需要在哪里添加此代码?如何获取Configuration对象?

    cfg.registerTypeOverride(
            new JsonSerializedUserType(LatLng.class),
            new String[] {"latlng"}
    );

0 个答案:

没有答案