Я следую примеру, указанному в приведенном ниже URL-адресе? Отображение столбца PostgreSQL JSON для типа значения Hibernate
Но всегда получайте следующее исключение:
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.<init>(SessionFactoryImpl.java:512)
Я использую TomEE в качестве Сервера. и пытается сохранить тело Json в столбце postgresql. Я пытаюсь отобразить объект pojos в структуру datatype postgres.
Любая идея, что может быть проблемой? или у любого есть лучшая техника для обработки, такая как сценарий? Пожалуйста, укажите мне этот источник.
script, используемый для создания таблицы сущностей:
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;
Entity Pojos выглядит следующим образом:
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@TypeDefs({ @TypeDef(name = "StringJsonObject", typeClass = StringJsonUserType.class) })
public class HistoryEntity {
    @Id
    private String id;
    private String userid;
    private String type;
    @Type(type = "StringJsonObject")
    private String history;
    private Date lastchanged;
}
Я использую lombok для определения объекта pojos.
Ниже приведен расширенный класс Dialect: Я пробовал как с зарегистрированными типами, так и с колонкой и Hibenate. Но оба они не работают.
import org.hibernate.dialect.PostgreSQL82Dialect;
public class JsonPostgreSQLDialect extends PostgreSQL82Dialect
    {
        @Inject
        public JsonPostgreSQLDialect()
        {
            super();
               this.registerColumnType(Types.JAVA_OBJECT, "json");
            // this.registerHibernateType(Types.JAVA_OBJECT, "json");
        }
    }
Для определения типа пользователя используется следующий класс:
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 <tt>java.sql.Types</tt>.
     *
     * @return int[] the typecodes
     * @see java.sql.Types
     */
    @Override
    public int[] sqlTypes()
    {
        return sqlTypesSupported;
    }
    /**
     * The class returned by <tt>nullSafeGet()</tt>.
     *
     * @return Class
     */
    @Override
    public Class returnedClass()
    {
        return String.class;
    }
    /**
     * Compare two instances of the class mapped by this type for persistence "equality". 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 "equality"
     */
    @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 <tt>index</tt>.
     *
     * @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;
    }
}
