我正在尝试使用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()时会生成空值?