`
janh
  • 浏览: 18289 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

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

    博客分类:
  • java
阅读更多
最近程序中用到子类继承,一个超类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,如:
EntryTask entryTask = (EntryTask)session.get(EntryTask.class,task.getId())

还有一种直接的方法,就是直接获得被代理的实体对象,hibernate生成的代理对象都实现了HibernateProxy接口,该接口提供了获取被代理对象的方法,可以这样来获取:
Object target = ((HibernateProxy)task).getHibernateLazyInitializer().getImplementation()

这样就可以进行类的比较转换了,这种方法虽然不复杂,但还是觉得罗唆。

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

难道真的是鱼与熊掌不可兼得吗?
分享到:
评论

相关推荐

    hibernate延迟加载解决

    这是因为,如果不使用延迟加载,加载一个实体可能会导致所有相关联的实体都被加载到内存中,从而严重影响性能。 **配置方式:** 要启用集合类型的延迟加载,需要在映射文件中为集合元素添加`lazy="true"`属性,...

    原生js延迟加载

    例如,一个通用的`LazyElement`类可以被`LazyImage`和`LazyVideo`类继承,每个子类可以覆盖或扩展父类的方法,实现特定类型的延迟加载。 现在,关于“自动播放轮播图”和“无缝滚动”效果,这两个功能进一步丰富了...

    SSH延迟加载的一个小DEMO

    3. **多对一关系的延迟加载**:与一对一关系类似,但通常在关联的反向端进行设置,即在子类中引用父类对象时使用延迟加载。 4. **级联加载**:通过`cascade`属性可以配置是否将加载操作级联到关联对象,比如`...

    php中通过虚代理实现延迟加载的实现代码

    这货是从 Martin 大神的《企业应用架构模式》中学到的,辅助 PHP 动态语言的特性,可以比 Java 轻松很多的实现延迟加载(LazyLoad...如果是用该代理来处理集合类型的延迟加载,还需要继承一个子类做特殊处理,以便外部

    ASP.NET Mvc开发之EF延迟加载

    延迟加载是Entity Framework (EF) 的一个重要特性,它允许我们在不立即加载数据的情况下构造查询,数据仅在实际使用时才从数据库中检索,从而优化性能。在*** MVC中实现EF的延迟加载涉及到对Entity Framework核心...

    浅谈Java中父类与子类的加载顺序详解

    以下是Java中父类与子类加载顺序的详细解释: 1. **静态初始化**: - 首先,JVM会加载类的静态部分。这意味着先加载所有静态变量的初始化,并执行静态初始化块(如果有的话)。在给定的例子中,无论父类还是子类,...

    简单实现Cglib子类代理

    Cglib子类代理是Java动态代理的一种实现方式,它主要通过字节码技术在运行时动态创建一个目标对象的子类,以此来实现代理功能。Cglib是一个强大的高性能的代码生成库,它在许多AOP(面向切面编程)框架中被广泛应用...

    JAVA子类与继承实验报告

    JAVA子类与继承实验报告 实验1 中国人与美国人 实验2 面积之和

    swift-UIButton子类用于加载和转换动画

    在Swift开发中,按钮(UIButton)是用户界面中不可或缺的元素,它允许用户与应用进行交互。本主题将深入探讨如何创建一个UIButton的子类,该子类支持加载和转换动画,以提升用户体验并增强应用的视觉吸引力。这种...

    类加载机制与动态代理的测试题

    ### 类加载机制与动态代理知识点解析 #### 一、选择题知识点详解 ##### 1. 类加载的过程 类加载过程主要包括以下几个步骤: - **加载**(A):这是类加载的第一个阶段,在这个阶段,JVM负责读取类的二进制数据到...

    父类赋值给子类

    在编程领域,特别是面向对象编程中,"父类赋值给子类" 是一个常见的操作。C# 作为一种强大的面向对象的语言,提供了多种方式来实现这种继承关系下的数据复制。这里我们将深入探讨如何在 C# 中进行父类属性到子类属性...

    子类、父类查询

    有关子类和父类。A是子类,Teacher是父类。A是Teacher 的一种(子类)会继承父类李非私

    自定义UIView子类

    在iOS开发中,自定义UIView子类是一种常见的需求,它能帮助我们实现特定的功能或界面效果,提升代码的可重用性和可维护性。这里我们将深入探讨如何利用XIB(Interface Builder)文件来创建和设计自定义的UIView子类...

    swift-一个小而灵活的UIButton子类动画加载进度完成动画

    这个名为"swift-一个小而灵活的UIButton子类动画加载进度完成动画"的项目,就是为了解决这个问题,通过创建一个自定义的`UIButton`子类,添加了动画显示加载进度和完成状态。 首先,我们来看一下这个项目的重点——...

    类加载器代码

    总结来说,类加载器是Java运行时环境的关键组件,它决定了类的生命周期和加载方式,是理解和优化JVM性能、实现动态加载、保障系统安全等方面不可或缺的知识点。深入理解类加载器的工作原理和机制,对于开发高效、...

    Hibernate加载方式与多态加载分析

    由于代理类并非实际实体的实例,因此不支持多态加载。相反,如果lazy设置为false,`load`方法的行为就与`get`方法类似,可以支持多态加载。`get`方法默认不使用CGLIB懒加载,所以在加载时会直接返回实体的真实类,这...

    13丨软件设计的里氏替换原则:正方形可以继承长方形吗?.pdf

    总的来说,里氏替换原则强调了设计上的灵活性和可扩展性,避免了因继承关系不合理导致的代码维护困难。遵循这一原则,我们可以构建出更加稳定、健壮的软件系统,使得新增的子类可以无缝地融入现有的代码结构,而不会...

    在父类获取子类属性

    在Java编程语言中,"在父类获取子类属性"是一个常见的需求,特别是在设计模式、继承和多态性等核心概念的应用中。这个主题涉及到面向对象编程的基本原理,特别是子类继承父类后如何访问和操作子类特有的属性。下面...

    Java入门 类与子类

    本代码用类和子类实现了输出复数的功能。适合初学者参考学习

    再次详细说明在继承中的程序执行顺序,子类与父类到底哪个先执行

    本文将深入探讨在继承中的程序执行顺序,以及子类与父类的执行顺序问题。 首先,我们需要了解Java或Python等面向对象语言中类的构造过程。当一个类实例化时,其构造函数(在Java中是`构造器`,在Python中是`__init_...

Global site tag (gtag.js) - Google Analytics