【发布时间】:2018-01-26 02:54:01
【问题描述】:
我正在尝试将我的 spring mvc 项目数据库从 mongodb 迁移到 postgresql。 春季版 4.3.8.RELEASE 休眠版本 5.2.10.Final Postgresql 数据库版本是 9.6
我正在尝试为以下实体实现创建、读取、更新操作。
BeneficiaryData.java
@Document(collection = "beneficiary_data")
public class BeneficiaryData extends BaseEntity {
@Id
private String id;
private Integer beneficiaryId;
private Map<Integer, Object> customData;
private Map<Integer, List<Integer>> customMultipleData;
private Date lastUpdatedOn;
public BeneficiaryData() {
}
}
在 mongodb 中,该实体存储为 json 文档,并且字段 customData、customMultipleData、rcfData 从 json 到对象的转换由 spring data 处理。
为了将它存储在 postgresql 中,我想到了使用以下表结构,利用 postgresqls jsonb 类型。
CREATE TABLE ebbin.beneficiary_data
(
id integer NOT NULL DEFAULT nextval('bms_v21.beneficiary_data_id_seq'::regclass),
beneficiary_id integer NOT NULL,
custom_data jsonb,
custom_multiple_data jsonb,
last_updated_on timestamp(3) without time zone,
CONSTRAINT beneficiary_data2_pkey PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
为了处理两个 jsonb 类型,我实现了两个自定义休眠用户类型
JSONBCustomDataUserType.java
public class JSONBCustomDataUserType extends CollectionUserType implements ParameterizedType {
private static final String JSONB_TYPE = "jsonbCustomData";
public static final String CLASS = "CLASS";
@Override
public Class<Object> returnedClass() {
return Object.class;
}
@Override
public int[] sqlTypes() {
return new int[] { Types.JAVA_OBJECT };
}
// ... implementations for nullSafeGet, nullSafeSet ...
}
和JSONBCustomMultipleDataUserType.java
public class JSONBCustomMultipleDataUserType extends CollectionUserType implements ParameterizedType {
private static final String JSONB_TYPE = "jsonbCustomData";
public static final String CLASS = "CLASS";
@Override
public Class<Object> returnedClass() {
return Object.class;
}
@Override
public int[] sqlTypes() {
return new int[] { Types.JAVA_OBJECT };
}
// ... implementations for nullSafeGet, nullSafeSet ...
}
我的 postgresql 实体现在是 BeneficiaryData.java
@TypeDefs({
@TypeDef(name = "jsonbCustomData", typeClass = JSONBCustomDataUserType.class,
parameters = {@Parameter(name = JSONBCustomDataUserType.CLASS, value = "java.util.Map")}),
@TypeDef(name = "jsonbCustomMultipleData", typeClass = JSONBCustomMultipleDataUserType.class,
parameters = {@Parameter(name = JSONBCustomMultipleDataUserType.CLASS, value = "java.util.Map")})
})
@Entity
@Table(name = "beneficiary_data")
public class BeneficiaryData extends BaseEntity {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@Column(name = "beneficiary_id", nullable = false)
private Integer beneficiaryId;
@Type(type = "jsonbCustomData")
@Column(name = "custom_data", nullable = true)
private Map<Integer, Object> customData;
@Type(type = "jsonbCustomMultipleData")
@Column(name = "custom_multiple_data", nullable = true)
private Map<Integer, List<Integer>> customMultipleData;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "last_updated_on", length = 19)
private Date lastUpdatedOn;
public BeneficiaryData() {
}
// ...
}
还创建了一个自定义 postgresql 方言,以便可以注册新的用户类型。
CustomPostgreSqlDialect.java
public class CustomPostgreSqlDialect extends PostgreSQL95Dialect {
public CustomPostgreSqlDialect() {
super();
this.registerColumnType(Types.JAVA_OBJECT, "jsonbCustomData");
this.registerColumnType(Types.JAVA_OBJECT, "jsonbCustomMultipleData");
}
}
但是,当我尝试使用 session.save() 保存实体时,出现以下错误。
org.springframework.dao.InvalidDataAccessResourceUsageException: could not insert: [com.tcs.bms.persistence.entity.BeneficiaryData];
.
.
.
Caused by: org.postgresql.util.PSQLException: Unknown type jsonbCustomData.
我猜这与我将列类型 JAVA_OBJECT 注册到 jsonbCustomData 和 jsonbCustomMultipleData 有关
我这样说是因为当我尝试仅使用 jsonbCustomData 用户类型时(在注释掉实体中的 customMultipleData 字段并从表中删除之后),我能够成功插入、更新和获取数据。
知道我做错了什么吗?
【问题讨论】:
标签: java postgresql hibernate spring-mvc jsonb