我如何使用hibernate持久化json对象?

时间:2016-04-30 14:02:36

标签: java json hibernate

这是我的情况: 我有一个具有属性的类,可以是json类型或其他数据结构。

ObjectMapper m=new ObjectMapper();
m.readValue(json, new TypeReference<MiClase>() {
            });

}

我想使用hibernate继承此类,但我也想使用以下代码:

create

上面的代码工作正常,但是当我尝试将实体保存到数据库时,我得到以下错误:映射列数错误:MiClase.b类型:对象 然后我尝试更改然后我尝试将de对象类型更改为byte []但是在使用readValue方法时无法反序列化byte []的实例。在这种情况下,您建议我采取什么策略? 我正在使用postgresql

1 个答案:

答案 0 :(得分:0)

我对我的问题的评估感到失望,我认为它有所有逻辑,虽然我的英语不是很好,这个解决方案帮助了我,允许我将任何数据保存到数据库中: 解决方案是创建自定义类型:

public  class JacksonUserType implements UserType {

    private static final int[] SQL_TYPES = { Types.LONGVARCHAR };

    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        if (x == y) {
            return true;
        } else if (x == null || y == null) {
            return false;
        } else {
            return x.equals(y);
        }
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        return null == x ? 0 : x.hashCode();
    }

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

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
        if (value == null) {
            st.setString(index, null);
        } else {
            st.setString(index, convertObjectToJson(value));
        }
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
        String content = rs.getString(names[0]);
        if(content!=null){
            return convertJsonToObject(content);
        }
        return null;
    }

    Object convertJsonToObject(String content){
        try {
            ObjectMapper mapper = new ObjectMapper();
            JavaType type = createJavaType(mapper);
            return mapper.readValue(content, type);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    String convertObjectToJson(Object object){
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            return mapper.writeValueAsString(object);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        String json = convertObjectToJson(value);
        return convertJsonToObject(json);
    }

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

    /**
     * (optional operation)
     *
     * @param value
     *
     * @throws HibernateException
     */
    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) deepCopy(value);
    }

    /**
     * (optional operation)
     *
     * @param cached
     * @param owner
     *
     * @return the instance cached
     *
     * @throws HibernateException
     */
    @Override
    public Object assemble(Serializable cached, Object owner)
            throws HibernateException {
        return deepCopy(cached);
    }

    /**
     * By default we are expecting to use a simple object / not a collection (Set, List)
     *
     * @param mapper : instance jackson object mapper
     *
     * @return A jackson JavaType to specify wich object represent the json string representation
     *
     */
    public JavaType createJavaType (ObjectMapper mapper){
        return SimpleType.construct(returnedClass());
    }


    @Override
    public int[] sqlTypes() {
        return SQL_TYPES;
    }

    @Override
    public Class returnedClass() {
        return Object.class;
    }
}

您还可以使用抽象类的变体和抽象方法:returnedClass()而不使用泛型对象类型