我正在尝试映射以下实体:
我有一个Order实体,它包含不同类型的OrderData(也可以在多个Order实体之间共享),具体取决于实际的顺序(不同的产品,产品变体等):
//Simplified example
@Entity
@IdClass(OrderPK.class)
@Table(name = "tablename"
public class Order<T extends OrderData> {
@Id
@ManyToOne
@JoinColumn(name = "whatever")
private T orderData;
// Might be complicating stuff
@Id
@ManyToOne
@JoinColumn(name = "somecolumn")
private Account buyerAccount;
// ...
}
// OrderData base class
@Entity
@Table(name = "thatothertable"
@Inheritance(strategy=InheritanceType.JOINED)
public class OrderData {
@Id
@Column(name = "id")
private Long id;
// extra stuff
}
现在的问题是:我怎样才能加入OrderData的正确子类?
我希望能够写出这样的东西:
List<Order<CustomOrderData>> ordersWithCustomOrderData = this.orderDAO.findAllOrders();
并使用CustomOrderDatas获取所有Order实体。
有没有办法实现这个目标?
到目前为止,我的DAO代码如下所示:
public List<Order> findAllOrders() {
CriteriaBuilder cb = this.em.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
Root<Order> root = cq.from(Order.class):
cq.select(root):
return this.em.createQuery(cq).getResultList();
}
我如何更改DAO代码以支持泛型类型? 它真的可能吗?如果没有,是否有任何替代设计来实现可比较的结构和功能(具有不同OrderDatas的订单,能够搜索具有OrderData特定子类的订单)?
// Not working pseudo code of what i want
public <T extends OrderData> List<Order<T>> findAllOrders() {
CriteriaBuilder cb = this.em.getCriteriaBuilder();
// With createQuery(Order.class) i will get CrtieriaQuery<Order>
CriteriaQuery<Order<T>> cq = cb.createQuery(Order.class);
// as above
Root<Order<T>> root = cq.from(Order.class):
cq.select(root):
return this.em.createQuery(cq).getResultList();
}
答案 0 :(得分:0)
<强> 1。想法强>
为什么需要通用属性? JPA中不可能使用通用实体,但您可以将对Orderdata的引用放在:
private OrderData orderData;
<强> 2。想法强>
您可以在实体中保存此枚举,然后将OrderDataType.getClazz()
与OrderData1.getClass()
进行比较,您可以查询此类型。如果您使用的是JPA 2.1,则可以使用自定义Fieldconverter将完整的类名保存在数据库列中,然后查询该类。
public enum OrderDataType {
Order1(Order1.class);
private Class<? extends OrderData> clazz;
private OrderDataType(Clazz<? extends OrderData> clazz) {
this.clazz = clazz;
}
public Class<? extends OrderData> getClazz() {
return clazz;
}
}