title: How can I map postgresql json data type using Hibernate?
body: <p>I am following the example mentioned in the below URL ?
  <a href="https://stackoverflow.com/questions/15974474/mapping-postgresql-json-column-to-hibernate-value-type?rq=1">Mapping PostgreSQL JSON column to a Hibernate entity property</a></p>
  <p>But always get the following exception:</p>
  <pre><code>Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: 2000
      at org.hibernate.dialect.TypeNames.get(TypeNames.java:76)
      at org.hibernate.dialect.TypeNames.get(TypeNames.java:99)
      at org.hibernate.dialect.Dialect.getTypeName(Dialect.java:310)
      at org.hibernate.mapping.Column.getSqlType(Column.java:226)
      at org.hibernate.mapping.Table.validateColumns(Table.java:369)
      at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1305)
      at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
      at org.hibernate.internal.SessionFactoryImpl.&lt;init&gt;(SessionFactoryImpl.java:512)
  </code></pre>
  <p>I am using TomEE as the Server. and trying to store Json body to a postgresql column. I am trying to map the entity pojos to the postgres datatype structure.</p>
  <p>Any idea what could be the issue ? or does any has a better technique to handle such as scenario ? Please point me to that source.</p>
  <p>The script used to create the entity table is:</p>
  <pre class="lang-sql prettyprint-override"><code>    CREATE TABLE historyentity
      (
        id character varying(255) NOT NULL,
        userid character varying(255),
        lastchanged timestamp without time zone,
        type character varying(255),
        history json [],
        CONSTRAINT historyentity_pkey PRIMARY KEY (id),
        CONSTRAINT historyentity_userid_fkey FOREIGN KEY (userid)
            REFERENCES userentity (id) MATCH SIMPLE
            ON UPDATE NO ACTION ON DELETE NO ACTION
      )
      WITH (
        OIDS=FALSE
      );
      ALTER TABLE historyentity
        OWNER TO postgres;
      GRANT ALL ON TABLE historyentity TO postgres;
  </code></pre>
  <p>Entity Pojos look like as follows:</p>
  <pre class="lang-java prettyprint-override"><code>    @Entity
      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      @TypeDefs({ @TypeDef(name = &quot;StringJsonObject&quot;, typeClass = StringJsonUserType.class) })
      public class HistoryEntity {
      
          @Id
          private String id;
          private String userid;
          private String type;
          @Type(type = &quot;StringJsonObject&quot;)
          private String history;
          private Date lastchanged;
      
      }
  </code></pre>
  <p>I am using lombok to define the entity pojos.</p>
  <p>Following is the Dialect extended class:
  I have tried with both the registered types, Column and Hibenate. But both are not working out.</p>
  <pre class="lang-java prettyprint-override"><code>    import org.hibernate.dialect.PostgreSQL82Dialect;
      
      public class JsonPostgreSQLDialect extends PostgreSQL82Dialect
      
          {
              @Inject
              public JsonPostgreSQLDialect()
              {
                  super();
                     this.registerColumnType(Types.JAVA_OBJECT, &quot;json&quot;);
                  // this.registerHibernateType(Types.JAVA_OBJECT, &quot;json&quot;);
              }
          }
  </code></pre>
  <p>The following class is being used to define the User Type:</p>
  <pre class="lang-java prettyprint-override"><code>    import java.io.Serializable;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Types;
      
      import org.hibernate.HibernateException;
      import org.hibernate.engine.spi.SessionImplementor;
      import org.hibernate.usertype.UserType;
      
      
      public class StringJsonUserType implements UserType
      {
          private final int[] sqlTypesSupported = new int[]{ Types.JAVA_OBJECT };
      
          /**
           * Return the SQL type codes for the columns mapped by this type. The codes are defined on &lt;tt&gt;java.sql.Types&lt;/tt&gt;.
           *
           * @return int[] the typecodes
           * @see java.sql.Types
           */
          @Override
          public int[] sqlTypes()
          {
              return sqlTypesSupported;
          }
      
          /**
           * The class returned by &lt;tt&gt;nullSafeGet()&lt;/tt&gt;.
           *
           * @return Class
           */
          @Override
          public Class returnedClass()
          {
              return String.class;
          }
      
          /**
           * Compare two instances of the class mapped by this type for persistence &quot;equality&quot;. Equality of the persistent
           * state.
           *
           * @return boolean
           */
          @Override
          public boolean equals(Object x, Object y) throws HibernateException
          {
      
              if (x == null)
              {
      
                  return y == null;
              }
      
              return x.equals(y);
          }
      
          /**
           * Get a hashcode for the instance, consistent with persistence &quot;equality&quot;
           */
          @Override
          public int hashCode(Object x) throws HibernateException
          {
      
              return x.hashCode();
          }
      
          /**
           * Retrieve an instance of the mapped class from a JDBC resultset. Implementors should handle possibility of null
           * values.
           *
           * @param rs a JDBC result set
           * @param names the column names
           * @param owner the containing entity  @return Object
           */
          @Override
          public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
              throws HibernateException, SQLException
          {
              if (rs.getString(names[0]) == null)
              {
                  return null;
              }
              return rs.getString(names[0]);
          }
      
          /**
           * Write an instance of the mapped class to a prepared statement. Implementors should handle possibility of null
           * values. A multi-column type should be written to parameters starting from &lt;tt&gt;index&lt;/tt&gt;.
           *
           * @param st a JDBC prepared statement
           * @param value the object to write
           * @param index statement parameter index
           */
          @Override
          public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
              throws HibernateException, SQLException
          {
              if (value == null)
              {
                  st.setNull(index, Types.OTHER);
                  return;
              }
      
              st.setObject(index, value, Types.OTHER);
          }
      
          /**
           * Return a deep copy of the persistent state, stopping at entities and at collections. It is not necessary to copy
           * immutable objects, or null values, in which case it is safe to simply return the argument.
           *
           * @param value the object to be cloned, which may be null
           * @return Object a copy
           */
          @Override
          public Object deepCopy(Object value) throws HibernateException
          {
      
              return value;
          }
      
          /**
           * Are objects of this type mutable?
           *
           * @return boolean
           */
          @Override
          public boolean isMutable()
          {
              return true;
          }
      
          /**
           * Transform the object into its cacheable representation. At the very least this method should perform a deep copy
           * if the type is mutable. That may not be enough for some implementations, however; for example, associations must
           * be cached as identifier values. (optional operation)
           *
           * @param value the object to be cached
           * @return a cachable representation of the object
           */
          @Override
          public Serializable disassemble(Object value) throws HibernateException
          {
              return (String) this.deepCopy(value);
          }
      
          /**
           * Reconstruct an object from the cacheable representation. At the very least this method should perform a deep copy
           * if the type is mutable. (optional operation)
           *
           * @param cached the object to be cached
           * @param owner the owner of the cached object
           * @return a reconstructed object from the cachable representation
           */
          @Override
          public Object assemble(Serializable cached, Object owner) throws HibernateException
          {
              return this.deepCopy(cached);
          }
      
          /**
           * During merge, replace the existing (target) value in the entity we are merging to with a new (original) value
           * from the detached entity we are merging. For immutable objects, or null values, it is safe to simply return the
           * first parameter. For mutable objects, it is safe to return a copy of the first parameter. For objects with
           * component values, it might make sense to recursively replace component values.
           *
           * @param original the value from the detached entity being merged
           * @param target the value in the managed entity
           * @return the value to be merged
           */
          @Override
          public Object replace(Object original, Object target, Object owner) throws HibernateException
          {
              return original;
          }
      }
  </code></pre>