Muh*_*ziz 5 string postgresql hibernate spring-boot jsonb
由于 hibernate 本身不支持 JSONB,因此我实现了自定义类型。我可以毫无问题地从表 ad_my_table 读取数据。但是,在编写时我收到数据转换错误。我还尝试使用第三方解决方案,例如“hibernate-types”库,但遇到了相同的错误。
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我收到的错误:
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]
Run Code Online (Sandbox Code Playgroud)
小智 0
使用连接字符串将 Jsonb 类型创建为 clob jdbc:h2:mem:<table>;INIT=create domain if not exists jsonb as CLOB;、. 只要您将字段定义为实体中的字符串,这种方法就可以正常工作。如果您将 Entity 中的字段定义为 CustomJson 对象,那么它仅支持数据库读取操作。
这有效:
@Column(name = "config", columnDefinition = "jsonb")
@Type(type = "jsonb")
private String config;
Run Code Online (Sandbox Code Playgroud)
这不支持读取操作
@Column(name = "config", columnDefinition = "jsonb")
@Type(type = "jsonb")
private MyJsonObject config;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3052 次 |
| 最近记录: |