Shvalb
Shvalb

Reputation: 1933

Create Hibernate Type to save JSONObject with PostgreSQL

I'm using Postgres 9 and Hibernate 4 as ORM.

In Postgres there is an option of creating a table with json type column.

I would like in my Java code to be able to send JSONObject in queries so they would be transformed\converted to Postgres type.

How can I do that?

I need to Object:

  1. The first object extends from UserType.
  2. The 2nd object extends: extends AbstractSingleColumnStandardBasicType implements DiscriminatorType.

Is there any example for that??

Upvotes: 0

Views: 4648

Answers (2)

Vlad Mihalcea
Vlad Mihalcea

Reputation: 153730

You don’t have to create all these types manually, you can simply get them via Maven Central using the following dependency:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>1.0.0</version>
</dependency>

For more info, check out the Hibernate Types open-source project.

Now, your mapping can use the JsonType, like this:

@Entity(name = "Book")
@Table(name = "book")
@TypeDef(
    name = "json", 
    typeClass = JsonType.class
)
public class Book {
 
    @Id
    @GeneratedValue
    private Long id;
 
    @NaturalId
    private String isbn;
 
    @Type( type = "json" )
    @Column(columnDefinition = "jsonb")
    private JsonNode properties;
 
    //Getters and setters omitted for brevity
}

That's it!

Upvotes: 2

SwampDev
SwampDev

Reputation: 657

Just had to spend some time on this and this worked for me:

    public class JSONUserType implements UserType {

        private static final int[] SQL_TYPES = { Types.LONGVARCHAR };
    @Override
    public Object assemble(Serializable cached, Object owner)
            throws HibernateException {
        return deepCopy(cached);
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        if (value == null)
            return value;
        try {
            return new JSONObject(((JSONObject) value).toString());
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return ((JSONObject) value).toString();
    }

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

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

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

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

    @Override
    @SuppressWarnings("unchecked")
    public Class returnedClass() {
        return JSONObject.class;
    }

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

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

        try {
            return new JSONObject(jsonString);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

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

            st.setObject(index, ((JSONObject) value).toString(),Types.OTHER);
        }

    }

}

Upvotes: 0

Related Questions