[英]Join generic type with JPA and Criteria API
i'm trying to map the following entity: 我正在尝试映射以下实体:
I have an Order entity that contains different types of OrderData(can also be shared between multiple Order entities), depending on the actual order(different produckts, product variants etc): 我有一个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
}
Now the problem is: how can i get this to join the right subclass of OrderData? 现在的问题是:我如何才能将其加入OrderData的正确子类? I want to be able to write something like this:
List<Order<CustomOrderData>> ordersWithCustomOrderData = this.orderDAO.findAllOrders();
我希望能够这样写:
List<Order<CustomOrderData>> ordersWithCustomOrderData = this.orderDAO.findAllOrders();
and get all Order entities with CustomOrderDatas. 并使用CustomOrderDatas获取所有Order实体。 Is there a way to achieve this?
有没有办法做到这一点?
So far my DAO codes looks like this: 到目前为止,我的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();
}
How would i have to change the DAO code to support the generic type? 我将如何更改DAO代码以支持通用类型? Is it actually possible?
真的有可能吗? If not, is there any alternative design to achieve a comparable structure and functionability (Orders with different OrderDatas, ability to search for Orders with specific subclass of OrderData)?
如果不是,是否有任何替代设计来实现可比的结构和功能(具有不同OrderData的订单,具有OrderData特定子类的Orders的搜索能力)?
// 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();
}
1. Idea 1.想法
Why do you need a generic Attribute? 为什么需要通用属性? Generic entities are not possible in JPA but you could just put the reference to a Orderdata as:
通用实体在JPA中是不可能的,但是您可以将对Orderdata的引用放置为:
private OrderData orderData;
2. Idea 2.想法
You can save this enum in your entity and then compare OrderDataType.getClazz()
to your OrderData1.getClass()
and you can query for this types. 您可以将该枚举保存在您的实体中,然后将
OrderDataType.getClazz()
与OrderData1.getClass()
比较,然后可以查询此类型。 If you are using JPA 2.1 you can save the full classname in the database column with a custom Fieldconverter and then query for the class. 如果使用的是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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.