gpt4 book ai didi

string - 与 JSONB 相关的 PostgreSQL Hibernate-types 数据转换错误

转载 作者:行者123 更新时间:2023-12-03 20:52:02 28 4
gpt4 key购买 nike

由于 hibernate 本身不支持 JSONB,因此我实现了自定义类型。我可以毫无问题地从表 ad_my_table 读取数据。但是,在写入时出现数据转换错误。我还尝试使用“hibernate-types”库等第 3 方解决方案,但遇到了同样的错误。

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;
}
}

CustomPostgreSQLDialect.class 扩展 PostgreSQL10Dialect :
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:<table>;INIT=create domain if not exists jsonb as CLOB; .当您在实体中将字段定义为 String 时,这可以正常工作。如果您将 Entity 中的字段定义为 CustomJson 对象,则它仅支持数据库读取操作。
这有效:

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

关于string - 与 JSONB 相关的 PostgreSQL Hibernate-types 数据转换错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62360439/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com