Spring CRUDRepository在Postgres / Hibernate / Jackson中保存嵌套的Json列

时间:2018-03-07 21:01:39

标签: json spring postgresql hibernate jpa

我正在尝试使用Spring / Hibernate / Jackson在Postgres数据库中保存实体。

实体JSON:

{"Block": {"hash":"abc123", "tx":[{"hash":"xyz321", "number":5}, {"hash":"xyz321", "number":5}]}}

我希望Java中的Transaction实体有一个String字段来表示哈希,一个JSON对象/字符串表示输入列表(自定义实体);即交易清单将是:(存储为数据库中的json)

"tx":[{"hash":"xyz321", "number":5}, {"hash":"xyz321", "number":5}]

我的交易实体:

public class Transaction implements Serializable {

    @JsonProperty("hash")
    @Column(name = "hash", unique = true)
    private String hash;

    @JsonProperty("vin")
    @Column(name = "vin", nullable = false)
    @Type(type = "TxVinUserType")
    @JsonDeserialize(using = vinDeserialiser.class)
    public List<TxVin> txVin;
}

我的自定义Hibernate UserType:

public class TxVinUserType implements UserType {

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

@Override
public Class<TxVin> returnedClass() {
    return TxVin.class;
}

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

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

    return x.hashCode();
}

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

    PGobject o = (PGobject) rs.getObject(names[0]);
    if (o.getValue() != null) {
        try {
            return new ObjectMapper().readValue(o.getValue(), TxVin.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return new TxVin();

}

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

    if (value == null) {
        st.setNull(index, Types.OTHER);
    } else {
        String s;
        try {
            s = new ObjectMapper().writeValueAsString(value);
            st.setObject(index, s, Types.OTHER);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

@Override
public Object deepCopy(Object value) throws HibernateException {
    if (value == null) {
        return null;
    }

    if (!(value instanceof TxVin)) {
        return null;
    }

    return (TxVin) value;
}

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

@Override
public Serializable disassemble(Object value) throws HibernateException {
    Object copy = deepCopy(value);

    if (copy instanceof Serializable) {
        return (Serializable) copy;
    }

    throw new SerializationException(
            String.format("Cannot serialize '%s', %s is not Serializable.", value, value.getClass()), null);
}

@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
    return deepCopy(cached);
}

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

}

我正在使用Spring Data的CrudRepository。当我尝试保存事务(具有有效的txVin列表)时,我收到此错误:

"org.postgresql.util.PSQLException: ERROR: null value in column "vin" violates not-null constraint"

所以我的问题是,为什么Spring在尝试使用CrudRepository.save()时会生成空值?

0 个答案:

没有答案