子类与代理延迟加载,难道是鱼与熊掌不可兼得?

最近程序中用到子类继承,一个超类Task,有几个子类如 EntryTask和GroupTask,对应同一张数据库表,用一个discriminator字段来区分是哪一个子类。

在需要判断hibernate返回的对象是哪一个子类时遇到麻烦,如果返回的不是代理对象,使用if(task instanceof EntryTask)这样的语句就可以,但是如果是代理对象就有问题了,因为其他地方有对Task的多对一关联,并且关联处指定的父类肯定是Task超类,不会去指定具体哪个子类,这样一旦延迟加载生成的是Task类的代理对象。

该对象只instanceof Task类,而不是它的任何子类,即使在加载了实体类数据后,该代理对象的类属性也不会改变,仍旧只instanceof Task超类,而且在其他地方查询时,对于相同的id,hibernate返回的还是以前返回过的代理对象(hibernate会保持返回的一致性)。

当然要判断该代理对象到底是哪个具体子类还是有办法的,可以在Task超类中加一个只读的discriminator属性,通过discriminator判断该代理对象是哪个子类,但是象EntryTask entryTask = (EntryTask)task这样的转换还是不行的,java只知道它是个Task,除非再通过id来load或get,如:[code]EntryTask entryTask = (EntryTask)session.get(EntryTask.class,task.getId())[/code]
还有一种直接的方法,就是直接获得被代理的实体对象,hibernate生成的代理对象都实现了HibernateProxy接口,该接口提供了获取被代理对象的方法,可以这样来获取:
[code]Object target = ((HibernateProxy)task).getHibernateLazyInitializer().getImplementation()[/code]
这样就可以进行类的比较转换了,这种方法虽然不复杂,但还是觉得罗唆。

现在的解决办法是不使用延迟加载,设置Task类映射lazy="false",并且在查询时使用eager-fetch,这样它就不会返回代理对象了,对我们这个应用来说性能影响也不大。

难道真的是鱼与熊掌不可兼得吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值