0

Problem: I'm gonna use [Hibernate-Types][1] by @vlad-mihalcea and I need to implement an Hibernate type for raw JSON values in my entity:

public class Entity {
  ...
  @Type(type = "rawjson") // or rawjsonb
  private String json;
}

For (string) 'json' type I've implemented:

public class RawJsonStringType extends ImmutableType<String> {

    public RawJsonStringType() {
        super(String.class);
    }

    @Override
    protected String get(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
        return rs.getString(names[0]);
    }

    @Override
    protected void set(PreparedStatement st, String value, int index, SharedSessionContractImplementor session) throws SQLException {
        st.setString(index, value);
    }

    @Override
    public int[] sqlTypes() {
        return new int[] { JAVA_OBJECT }; // it creates a 'json' column
    }

}

And for (binary) 'jsonb' type:

public class RawJsonBinaryType extends ImmutableType<String> {

    public RawJsonBinaryType() {
        super(String.class);
    }

    @Override
    protected String get(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
        return rs.getString(names[0]);
    }

    @Override
    protected void set(PreparedStatement st, String value, int index, SharedSessionContractImplementor session) throws SQLException {
        st.setString(index, value);
    }

    @Override
    public int[] sqlTypes() {
        return new int[] { JAVA_OBJECT - 1 }; // to have a 'jsonb' column, must be registered in the dialect: registerColumnType(Types.JAVA_OBJECT - 1, "json");
    }

}

But when I test it, it fails with the following:

Caused by: org.postgresql.util.PSQLException: ERROR: column "rawjson" is of type json but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 123

2 Answers 2

1

Just map it as a JsonNode and it will work. So, from String, you need to build the Jackson JsonNode.

If you want to map it as String, you'd have to write a new custom Type. But, why would you do that?

Sign up to request clarification or add additional context in comments.

5 Comments

How about java.util.Date? It's a very common mapping choice and it's not immutable. Luckily, Hibernate can handle both cases just fine.
I'm not following. Would you please elaborate. The reason I talked about immutability was that I thought since our type is in fact immutable, then implementing it this way bring us performance improvement (deep copy, etc). What am I missing here?
I find that mapping JSON columns to a pre-defined Java Object or a JsonNode allows much better flexibility on the application side. What are you going to do with the JSON property as a String?
I just need to store it and then retrieve it as raw JSON in future. I completely appreciate the flexibility benefit. But my question is if it is possible to use immutable implementation vs mutable implementation (ignoring the flexibility benefit), which one is better (in terms of performance or anything else?).
Theoretically, immutable types might perform slightly better, but only a benchmark can show the difference.
0

It was almost correct:

@Override
protected void set(PreparedStatement st, String value, int index, SharedSessionContractImplementor session) throws SQLException {
    st.setObject(index, value, Types.OTHER);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.