【发布时间】:2022-01-26 08:09:49
【问题描述】:
我有一个奇怪的问题,我很难理解 Java 中“静态上下文”的本质,尽管关于这个主题有很多 SO 问题。
TL;DR:
我有一个设计缺陷,其中...
这行得通:
List<OrderExtnTrans> list = orderType.getOrderExtnTransList();
this.dtoOrderExtnTransList = list.stream().map(OrderExtnTrans::toDto).collect(Collectors.toList());
但这不是:
this.dtoOrderExtnTransList = orderType.getOrderExtnTransList().stream().map(OrderExtnTrans::toDto).collect(Collectors.toList());
第二个版本显示的错误是“Non-static method cannot be referenced from a static context”。
长版:
对象模型: 该模型由特定于业务类型的订单(例如证券交易所、支付)组成,这些订单通过“InheritanceType.JOINED”继承策略从订单实体继承。 父订单可以使用该订单的业务类型特定 DTO 对象进行参数化,例如 DtoStockExchangeOrder。这是为了使 JPA 对象可以映射到实体中的 DTO 等效项,而不是服务中(我之前做过。它有效,但它“不太干净”)。
JPA 订单:
@Entity
@Table(name = "ORDER_BASE")
@Inheritance(strategy = InheritanceType.JOINED)
public class Order<DtoOrderType extends DtoOrder> implements Serializable {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "order", orphanRemoval = true)
private List<OrderExtnTrans> orderExtnTransList = new ArrayList<>();
}
JPA 订单 - 业务类型特定示例:
@Entity
@Table(name = "ORDER_STEX")
@Inheritance(strategy = InheritanceType.JOINED)
public class OrderStex extends Order<DtoOrderStex> implements Serializable {
同样,DTO 订单遵循相同的模式,可以使用业务类型特定的 JPA 实体对其进行参数化,以启用相关映射:
DTO 订单:
public class DtoOrder<OrderType extends Order> extends DtoEntity {
DTO 订单 - 业务类型特定示例
public class DtoOrderStex extends DtoOrder<OrderStex> {
它继承的 DTOEntity 类只是一个“包装”类,由一个 ID 和一个名称组成。
现在是棘手的部分: DTOOrder 类有一个构造函数,它填充所有业务类型共有的字段,如流程状态转换列表、订单在其生命周期中经历的(放置、取消、执行等)。继续以流程状态转换为例,这些也被建模为数据库中的 JPA 实体,以及它们对应的 DTO 对应物(同样参数化,该部分工作正常)。
这里是构造函数:
public DtoOrder(OrderType orderType) {
super(orderType);
// this is the part from above, which works (but it shows a warning: Unchecked assignment: 'java.util.List' to 'java.util.List<com.tradingvessel.core.persistence.model.OrderExtnTrans>' )
List<OrderExtnTrans> list = orderType.getOrderExtnTransList();
this.dtoOrderExtnTransList = list.stream().map(OrderExtnTrans::toDto).collect(Collectors.toList());
// this is how I would have expected it to work, but it does not, with the error shown above: "Non-static method cannot be referenced from a static context"
this.dtoOrderExtnTransList = orderType.getOrderExtnTransList().stream().map(OrderExtnTrans::toDto).collect(Collectors.toList());
}
如果我注释掉非工作版本,应用程序将按预期运行并且不会引发错误,因此“从逻辑上讲”,这是可行的。但是JAVA不允许它像第二版那样开发。
如果我使用“Order”而不是 OrderType,它也可以正常工作,但显然会在其他地方抛出错误,因为构造函数的签名发生了变化。我假设另一种方法是根据构造函数的调用者对方法进行参数化,或者对父类 DtoOrder 进行参数化以了解子类的类型,但应该有更好的方法吗?
我做错了什么,为什么高版本能按预期工作?
【问题讨论】:
-
所以忘记使用变量
list的工作的表面差异,主要区别在于工作的使用OrderExtnTrans但失败的使用OrderExtnAdd。您能否编辑您的问题以显示更多这些类 - 特别是显示它们的toDto方法(特别是如果一个是static) -
@racraman 抱歉,这是一个复制粘贴错误,它们在实际代码中是同一个类。稍后我将添加更多详细信息
-
dtoOrderExtnTransList的类型是什么,getOrderExtnTransList()的返回是什么? -
您能否编辑您的问题以获得可重现的示例,我们没有正确的类并且缺少某些方法。我怀疑您的原始类和类型无法正确推断。
-
请出示
OrderType class,谢谢
标签: java spring hibernate dictionary jpa