【发布时间】:2017-10-01 03:22:33
【问题描述】:
我正在使用 Spring Boot 和 Hibernate 开发 REST 服务,并使用 JPA 实现持久性。有一组 UML 人员定义的类看起来很难实现,我还不知道该怎么做。
这些类用于存储类型化数据。一组类派生自一个名为 XBRLUnitType 的类,并包括一个名为 moneyUnitType 的类,该类包含一个货币代码。另一组类包含一个 Quantity,它是一个“值”加上数据类型。其中一个 Quantities 是 Monetary,它有一个 Float 来保存该值,并且它具有 currencyUnitType,如下所示:
@Embeddable
public class Monetary extends Quantity {
@JsonProperty("itemUnit")
@Embedded
private monetaryItemType itemUnit = null;
}
@Embeddable
public class Quantity {
@JsonProperty("uncertainty")
private Float uncertainty = null;
@JsonProperty("value")
private Float value = null;
@JsonProperty("itemUnit")
@Embedded
private XBRLItemType itemUnit = null;
}
@Embeddable
public class monetaryItemType extends XBRLItemType {
}
@Embeddable
public class XBRLItemType {
@JsonProperty("symbol")
protected String symbol = null;
@JsonProperty("unitID")
private String unitID = null;
@JsonProperty("unitName")
private String unitName = null;
}
然后在其中一个类中我声明了这个字段:
@Entity
public class Device {
... many other fields
@Embedded
private Monetary currency = null;
... many other fields
}
为了创建一个项目,我发布了一些 JSON,我看到 JSON 被正确解释,生成的 Java 对象中的货币字段被正确填写。
BUT ... 在 Hibernate 调试输出中 Hibernate 不会在数据库中创建与货币列匹配的列。
create table device (dtype varchar(31) not null, deviceid binary not null, description varchar(255), meta varchar(255), name varchar(255), documentation varchar(255), type integer, cost float, manual varchar(255), manufacture_date_time binary(255), manufacturer varchar(255), model_number varchar(255), purchase_date_time binary(255), serial_number varchar(255), warranty_promise varchar(255), has_built_in_meter boolean, inverter_type integer, phase_type integer, ground_coverage_ratio float, hasdcoptimizer boolean, has_micro_inverter boolean, module_type integer, firmwareid integer, nameplateid binary, pv_arrayid binary, sub_arrayid binary, pv_stringid binary, systemid binary, primary key (deviceid))
另外,数据库表没有匹配的列。
当我使用 GET 请求检索对象时,货币字段为空。大概是因为它没有数据库列。
在这本在线电子书中我发现了一个声明,Java Persistence 不支持复杂的@Embedded 对象:https://en.wikibooks.org/wiki/Java_Persistence/Embeddables
那是“JPA 规范不允许在可嵌入对象中继承”......显然我有继承。而且,“JPA 1.0 规范只允许嵌入对象中的基本关系,因此不支持嵌套嵌入”,我相信我所拥有的是嵌套嵌入。
我研究的一件事是转换器:
@Embedded
@Column(name="currency", columnDefinition="VARCHAR")
@Convert(converter = MonetaryConverter.class, attributeName="currency")
private Monetary currency = null;
但是,MonetaryConverter 类的方法从未被调用过。
还有这个:
@Type(type="com.amzur.orangebuttonapi.model.primitives.Monetary")
@Columns(columns = {
@Column(name="value"), @Column(name="uncertainty"), @Column(name="currencyCode")
})
@ColumnTransformers(value = {
@ColumnTransformer(
forColumn="value",
read="value",
write="?"
),
@ColumnTransformer(
forColumn="uncertainty",
read="uncertainty",
write="?"
),
@ColumnTransformer(
forColumn="currencyCode",
read="itemUnit.symbol",
write="?"
)
})
private Monetary currency = null;
它应该创建一些列来存储一些可以解决问题的值。
基本上,我正在寻找持久化 Embeddable 的方法,这一定很复杂。
否则我需要以更多表为代价将这些类转换为@Entity?
更新:上面做了一点澄清。
在 javax.persistence 注释 (https://javaee.github.io/javaee-spec/javadocs/) 中,我看到 @Convert 适用于基本属性。因此@Convert 不适用于我正在处理的非基本属性。
【问题讨论】:
-
边缘:a) 从大写字母开始上课 (
monetaryItemType) b) 人们报告派生的空课程有一些困难。 -
我相信所有目标都可以在纯 JPA 2.0/2.1(和新鲜的 2.2)中实现,多年来没有强烈的理由使用方言。 EDIT 2.0 比 1.0 有很多很多的优势
-
为什么
monetaryItemType实际上没有字段currency?如果它真的有然后更新你的帖子,包括它。对于任何试图处理继承的嵌入式字段的 JPA 提供程序,我也希望有一个鉴别器 -
monetaryItemType 确实是一个空的派生类
-
对了,你说的这个神奇的领域“货币”在哪里?!
in one of the classes非常精确……
标签: spring hibernate jpa spring-data-jpa