hibernate延迟加载 与 web应用 独立缓存架构的冲突
延迟加载(LazyLoading)是啥玩意儿?估计地球人都知道,它的意义在于只在需要的时候才去加载必要的数据,这样可以避免即时加载所带来的不必要的系统开销(教科书是这么说的)。另外,教科书中还举了个例子。例如某个User对象在加载时会同时读取其所关联的多个地址(Address)对象,对于需要对Address进行操作的应用来说,关联数据的自动加载机制非常有效。不过呢如果我们只想要获得User的性别(sex)属性,而不关心User的地址(Address)信息,那么加载Address的特性就显得多余,并且造成了极大的性能浪费。为了获得User的性别属性,我们可能还要同时从数据库中读取数条无用的地址数据,这导致了大量无谓的系统开销,因此延迟加载就这么闪亮登场,基本上目前绝大多数的ORM都具有延迟加载的特性。
好处如此多,为啥要慎用?
第一,延迟加载搞不好就容易导致N+1select问题,性能反而不能保障
第二,延迟加载一般是在ORM中采用字节码增强方式来实现,这种方式处理后的对象往往会导致对象序列化失效,而在大型web应用中一般都会采用独立的缓存架构,一但应用系统引入独立的缓存系统对应用数据对象进行缓存,采用延迟加载后的对象序列化将失效,导致缓存失败。
第三,ORM中的延迟加载将业务对象的加载关系搞得不清不楚,如果某天想换ORM,那么还得针对不同的ORM处理延迟加载关系,即使不还ORM后来人想理解加载关系也会很头疼。
第四,延迟加载目的是为了提高性能,减少系统消耗,但是目前硬件处理能力已经大大提高,对于这点系统消耗一般还是可以承受,即使说有性能问题,也可以通过增加廉价PC来均摊负载,提高性能。
第五,从另外一方面考虑,ORM需要承担的仅仅是ORM,和事务、缓存等特性一样,它们应该由其他更有资格的家伙来承担,不需要搞那么负载,否则对于以后的底层扩展,那可是一个艰巨的工作。
建议,没有必要不要使用ORM中延迟加载特性,除非你的系统性能实在是不行了,需要延迟加载来避免这类系统消耗,那时你再考虑使用。而即使你要使用延迟加载特性,也建议你考虑清楚,是否要增加独立的应用缓存等等,有时可能根本原因在于系统的设计问题。
转http://blog.csdn.net/lovingprince/archive/2009/12/28/5089823.aspx
目前开发的项目中,想应用memcached,但遭遇hibernate延迟加载的问题,导致延迟加载的对象在序列化时失败,这样缓存无法应用。(暂时想用的解决办法就是去掉延迟加载,自己实现一对多关系的关联,这个改动是有多大,可想而知,所以设计很重要。)