I have an odd problem, where I am struggling to understand the nature of "static context" in Java, despite the numerous SO questions regarding the topic.
TL;DR:
I have a design flaw, where ...
This works:
List<OrderExtnTrans> list = orderType.getOrderExtnTransList();
this.dtoOrderExtnTransList = list.stream().map(OrderExtnTrans::toDto).collect(Collectors.toList());
But this does not:
this.dtoOrderExtnTransList = orderType.getOrderExtnTransList().stream().map(OrderExtnTrans::toDto).collect(Collectors.toList());
The error shown in the second version is "Non-static method cannot be referenced from a static context".
The long version:
Object Model: The model consists of Business Type specific orders (eg. Stock exchange, payments), which inherit from a an order entity via an "InheritanceType.JOINED" inheritance strategy. The parent order can be parameterized with the business type specific DTO object of that order, so for example DtoStockExchangeOrder. This is to enable, that JPA objects can be mapped to their DTO equivalent within the Entity, rather than in a service (which I did previously. It worked, but its "less clean").
JPA Order:
@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 Order - Business Type specific example:
@Entity
@Table(name = "ORDER_STEX")
@Inheritance(strategy = InheritanceType.JOINED)
public class OrderStex extends Order<DtoOrderStex> implements Serializable {
Likewise, DTO orders follow the same pattern, where they can be parameterized with the business type specific JPA entity, to enable the relevant mapping:
DTO Order:
public class DtoOrder<OrderType extends Order> extends DtoEntity {
DTO Order - Business Type Specific Example
public class DtoOrderStex extends DtoOrder<OrderStex> {
The DTOEntity class it inherits from is just a "wrapper" class, consisting of an ID and a name.
Now the tricky part: The DTOOrder class has a constructor which populates the fields that are common to all business types, like the list of process status transitions, an order goes through in its life cycle (placed, cancelled, executed, etc..). Staying with the example of the process status transitions, these are also modelled as JPA entities in the database, with their corresponding DTO counterparts (likewise parameterized, that part works fine).
Here the constructor:
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());
}
If I comment out the non-working version, the application behaves as expected and throws no error, so "logically", this works. But JAVA does not allow it as developed in the second version.
If instead of OrderType I use "Order", it works as well, but obviously throws errors elsewhere, because the signature of the constructor changed. I assume another approach would be to parameterise the method based on the the caller of the constructor or to parameterise the parent class DtoOrder to know the type of the child class, but there should be a better way?
What am I doing wrong, and why does the upper version work as expected?