Java Reference
In-Depth Information
Coupon coupon = pendingOrder.getCoupon();
if (coupon instanceof PercentageDiscountCoupon) {
PercentageDiscountCoupon percentageCoupon =
(PercentageDiscountCoupon)coupon;
}
else if (coupon instanceof FreeShippingCoupon) {
FreeShippingCoupon freeShippingCoupon =
(FreeShippingCoupon)coupon;
}
This code will certainly work with regular Java objects, but it won't work when the
application uses Hibernate proxies to implement lazy loading. If Hibernate lazily
loads a Coupon , then PendingOrder.getCoupon() will return a proxy rather than the
real Coupon . Unfortunately, the trouble with proxies is that they do not work cor-
rectly with instanceof and do not support downcasting. A Coupon proxy will never
appear to be an instance of FreeShippingCoupon or PercentageDiscountCoupon ,
and so neither call to instanceof will return true . Certainly, using instanceof is
generally not considered to be good style, but it is useful in cases such as this.
An application can work around this problem by calling Hibernate.get-
Class() , which is a static method that returns an object's true class:
Class trueClass = Hibernate.getClass(coupon);
if (PercentageDiscountCoupon.class.isAssignableFrom(trueClass)) {
}
The trouble with this solution is that it pollutes application code with calls to
Hibernate API s.
The other problem with proxies is that it is not possible to downcast a refer-
ence to a proxy. The downcasts in the previous code will fail if the Coupon is a
proxy. The workaround described in the Hibernate manual is to use parallel hier-
archy of interfaces and downcast to an interface instead of a concrete class:
interface ICoupon {..};
interface IPercentageDiscountCoupon extends Coupon {…};
if (PercentageDiscountCoupon.
b
isAssignableFrom(Hibernate.getClass(coupon))) {
IPercentageDiscountCoupon percentageCoupon =
(IPercentageDiscountCoupon)coupon;
}
 
 
Search WWH ::




Custom Search