String 与JSONB相关的PostgreSQL Hibernate类型数据转换错误

String 与JSONB相关的PostgreSQL Hibernate类型数据转换错误,string,postgresql,spring-boot,hibernate,jsonb,String,Postgresql,Spring Boot,Hibernate,Jsonb,由于hibernate本机不支持JSONB,所以我实现了自定义类型。我可以毫无问题地从表ad_my_表中读取数据。然而,在编写时,我得到了数据转换错误。我还尝试使用第三方解决方案,如“hibernate类型”库,但也遇到了同样的错误 MyTable实体类: import com.sample.console.backend.dao.entity.JsonbUserType; import org.hibernate.annotations.ColumnDefault; import org.h

由于hibernate本机不支持JSONB,所以我实现了自定义类型。我可以毫无问题地从表ad_my_表中读取数据。然而,在编写时,我得到了数据转换错误。我还尝试使用第三方解决方案,如“hibernate类型”库,但也遇到了同样的错误

MyTable实体类

import com.sample.console.backend.dao.entity.JsonbUserType;

import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.GenerationType;
import javax.persistence.SequenceGenerator;
import javax.persistence.Column;
import javax.persistence.Enumerated;

@Entity
@Table(name = "ad_my_table")
@TypeDef(name = "jsonb", typeClass = JsonbUserType.class)
public class CustomClientEntity
{
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_table_id_seq")
    @SequenceGenerator(name = "my_table_id_seq", sequenceName = "ad_my_table_id_seq", allocationSize = 1)
    private Long id;

    @Column(name = "filename")
    private String fileName;

    @Column(name = "config", columnDefinition = "jsonb")
    @Type(type = "jsonb")
    private String config;

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public String getFileName()
    {
        return fileName;
    }

    public void setFileName(String fileName)
    {
        this.fileName = fileName;
    }

    public String getConfig()
    {
        return config;
    }

    public void setConfig(String config)
    {
        this.config = config;
    }
}
JsonbUserType.class实现UserType

import org.apache.commons.lang3.StringUtils;
import org.hibernate.usertype.UserType;
import org.postgresql.util.PGobject;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class JsonbUserType implements UserType {

   public static final String JSONB_TYPE = "jsonb";

   @Override
   public Class<String> returnedClass() {
       return String.class;
   }

   @Override
   public int[] sqlTypes() {
       return new int[]{ Types.JAVA_OBJECT };
   }

   @Override
   public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {

       if (names.length <= 0) { return null; }

       final String dbData = rs.getString(names[0]);

       String result = null;

       if (StringUtils.isNotBlank(dbData)) {
           String json = dbData.startsWith("\"") ? dbData.substring(1, dbData.length() - 1) : dbData;
           result = StringEscapeUtils.unescapeJson(json);
       }

       return result;
   }

   @Override
   public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
           throws HibernateException, SQLException {

       if (value instanceof String && StringUtils.isNotBlank((String)value))
       {
           PGobject pgObject = new PGobject();
           pgObject.setType(JSONB_TYPE);
           pgObject.setValue((String)value);
           st.setObject(index, pgObject, Types.OTHER);
       }
       else {
           st.setNull(index, Types.OTHER);
       }
   }

   @Override
   public Object deepCopy(Object value) throws HibernateException {
       return value;
   }

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

   @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 {
       assert (x != null);
       return x.hashCode();
   }

   @Override
   public Object assemble(Serializable cached, Object owner) throws HibernateException {
       return this.deepCopy( cached);
   }

   @Override
   public Serializable disassemble(Object value) throws HibernateException {
       return (String)this.deepCopy( value);
   }

   @Override
   public Object replace(Object original, Object target, Object owner) throws HibernateException {
       return original;
   }
}
import com.sample.console.backend.dao.entity.JsonbUserType;

import org.hibernate.dialect.PostgreSQL10Dialect;

import java.sql.Types;

public class CustomPostgreSQLDialect extends PostgreSQL10Dialect
{
    public CustomPostgreSQLDialect() {
        super();
        registerColumnType(Types.JAVA_OBJECT, JsonbUserType.JSONB_TYPE);
    }
}
Caused by: org.h2.jdbc.JdbcSQLDataException: Data conversion error converting "X'aced000...74227d' (AD_MY_TABLE: ""CONFIG"" ""JSONB"")"; SQL statement: insert into ad_my_table (config, filename, id) values (?, ?, ?) [22018-200]

Caused by: org.h2.message.DbException: Data conversion error converting "OTHER to JSON" [22018-200]
我收到的错误

import org.apache.commons.lang3.StringUtils;
import org.hibernate.usertype.UserType;
import org.postgresql.util.PGobject;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class JsonbUserType implements UserType {

   public static final String JSONB_TYPE = "jsonb";

   @Override
   public Class<String> returnedClass() {
       return String.class;
   }

   @Override
   public int[] sqlTypes() {
       return new int[]{ Types.JAVA_OBJECT };
   }

   @Override
   public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {

       if (names.length <= 0) { return null; }

       final String dbData = rs.getString(names[0]);

       String result = null;

       if (StringUtils.isNotBlank(dbData)) {
           String json = dbData.startsWith("\"") ? dbData.substring(1, dbData.length() - 1) : dbData;
           result = StringEscapeUtils.unescapeJson(json);
       }

       return result;
   }

   @Override
   public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
           throws HibernateException, SQLException {

       if (value instanceof String && StringUtils.isNotBlank((String)value))
       {
           PGobject pgObject = new PGobject();
           pgObject.setType(JSONB_TYPE);
           pgObject.setValue((String)value);
           st.setObject(index, pgObject, Types.OTHER);
       }
       else {
           st.setNull(index, Types.OTHER);
       }
   }

   @Override
   public Object deepCopy(Object value) throws HibernateException {
       return value;
   }

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

   @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 {
       assert (x != null);
       return x.hashCode();
   }

   @Override
   public Object assemble(Serializable cached, Object owner) throws HibernateException {
       return this.deepCopy( cached);
   }

   @Override
   public Serializable disassemble(Object value) throws HibernateException {
       return (String)this.deepCopy( value);
   }

   @Override
   public Object replace(Object original, Object target, Object owner) throws HibernateException {
       return original;
   }
}
import com.sample.console.backend.dao.entity.JsonbUserType;

import org.hibernate.dialect.PostgreSQL10Dialect;

import java.sql.Types;

public class CustomPostgreSQLDialect extends PostgreSQL10Dialect
{
    public CustomPostgreSQLDialect() {
        super();
        registerColumnType(Types.JAVA_OBJECT, JsonbUserType.JSONB_TYPE);
    }
}
Caused by: org.h2.jdbc.JdbcSQLDataException: Data conversion error converting "X'aced000...74227d' (AD_MY_TABLE: ""CONFIG"" ""JSONB"")"; SQL statement: insert into ad_my_table (config, filename, id) values (?, ?, ?) [22018-200]

Caused by: org.h2.message.DbException: Data conversion error converting "OTHER to JSON" [22018-200]

使用将Jsonb类型创建为clob的连接字符串,
jdbc:h2:mem:;INIT=创建域(如果不存在jsonb作为CLOB)。只要将字段定义为实体中的字符串,就可以很好地执行此操作。如果将实体中的字段定义为CustomJson对象,则它只支持DB读取操作

这项工作:

@Column(name = "config", columnDefinition = "jsonb")
    @Type(type = "jsonb")
    private String config;
这不支持读取操作

@Column(name = "config", columnDefinition = "jsonb")
    @Type(type = "jsonb")
    private MyJsonObject config;

你查清楚了吗?我也有同样的问题。它在实际对抗Postgres时有效,但在对抗H2时无效。我没有使用自定义方言来注册JSONB支持,而是使用了一个连接字符串,将JSONB类型创建为JSON(以解决H2 JSON==Postgres JSONB问题),但我仍然有相同的问题:
jdbc:H2:mem:;INIT=如果不存在JSONB作为JSON创建域