2012-06-15 41 views
0

这里是我的问题 -Hibernate的HQL和继承

有两类OrderPaymentType。订单将有一个PaymentType。现在PaymentType是一个抽象类,还有另外两个类叫做CreditCardPaymentTypePaypalPaymentType,它扩展了PaymentType类。在休眠模式下,它们被建模为Single_Table策略。 CreditCardPaymentType包含一个名为CreditCardNumber的字段。我正在写下面的HQL,我的意图是急切地加载CreditCardNumber实体。

session.createQuery("select order from Order as order " + 
       "inner join fetch order.paymentType.Unknown"); 

什么应该代替“未知”?由于PaymentType班对CrediCardNumber班一无所知,我可以在上面的查询中加入CreditCardNumber

在此先感谢。

回答

2

无论如何,你想要做的事情都不起作用。

在订单中,您无法制作类型为PaymentType的实体并使用休眠进行加载。 PaymentType是抽象的,因此它不能被实例化。从这样的数据库加载实体时,Hibernate需要一个构造函数。所以你不能映射抽象类,你只能映射具有至少一个无参数构造函数的实现类。

=>在Order的映射中,您必须指定order.paymentType是否为CreditCardPaymentTypePaypalPaymentType。这就解决了你的问题,因为那你知道什么是unknown

要解决您的任务:在数据库端,您可以在一个表中继续使用所有付款类型。在Java方面你有两种可能性(既意味着作为一个想法):

  1. 你让PaymentType不是抽象的,有两种方法boolean isCreditCardPayment()boolean isPaypalCardPayment(),并PaymentType包含数据库表中的所有列。你只使用这个班级,你忘记了PaypalPaymentTypeCreditCardPaymentType

  1. 在这两个PaypalPaymentType和映射CreditCardPaymentType你把在那里的条件,确保只有正确的支付类型的行被加载。按顺序删除属性paymentType,并作为替换添加引用两个Java类的两个属性paypalPaymentType和creditcardPaymentType。当加载Order时,两个属性中的一个将为空。为了方便起见,您可以创建一个方法PaymentType getPaymentType(),该方法返回非空付款类型,但这种方便的方法不能在HQL查询中使用。
+0

感谢您的回答。我感觉合理 :) – user977263

1

如果我错了,请纠正我。检查娄代码

session.createQuery("from Order as order " + 
"inner join fetch order.paymentType.class = CreditCardPaymentType"); 

按照该url

特殊属性类的访问在多态持久化的情况下,一个实例的鉴别值。嵌入在where子句中的Java类名将被转换为其鉴别值。来自Cat猫,其中cat.class = DomesticCat