Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate延迟加载应用程序设计_Java_Hibernate_Spring_Lazy Loading_Application Design - Fatal编程技术网

Java Hibernate延迟加载应用程序设计

Java Hibernate延迟加载应用程序设计,java,hibernate,spring,lazy-loading,application-design,Java,Hibernate,Spring,Lazy Loading,Application Design,我倾向于与框架及其声明性事务划分功能(例如,)结合使用 众所周知,hibernate尽可能做到非侵入性和透明性,但在使用延迟加载关系时,这证明更具挑战性 我看到许多具有不同透明度的设计方案 使关系不延迟加载(例如,fetchType=fetchType.EAGER) 这就是延迟加载的整个概念 使用Hibernate.Initialize(proxyObj)初始化集合 这意味着与DAO的耦合度相对较高 尽管我们可以使用initialize定义接口,但其他实现不保证提供任何等效的接口 将事

我倾向于与框架及其声明性事务划分功能(例如,)结合使用

众所周知,hibernate尽可能做到非侵入性和透明性,但在使用
延迟加载关系时,这证明更具挑战性


我看到许多具有不同透明度的设计方案

  • 使关系不延迟加载(例如,
    fetchType=fetchType.EAGER)
    • 这就是延迟加载的整个概念
  • 使用Hibernate.Initialize(proxyObj)初始化集合
    • 这意味着与DAO的耦合度相对较高
    • 尽管我们可以使用
      initialize
      定义接口,但其他实现不保证提供任何等效的接口
  • 将事务行为添加到持久的
    模型
    对象本身(使用或
    @Transactional
    • 我没有尝试过动态代理方法,尽管我似乎从未让@Transactional处理持久对象本身。可能是因为hibernate在代理服务器上运行
    • 交易实际发生时失去控制
  • 提供惰性/非惰性API,例如,
    loadData()
    loadDataWithDeps()
    • 强制应用程序知道何时使用哪个例程,同样是紧密耦合
    • 方法溢出,
      loadDataWithA()
      ,…,
      loadDataWithX()
  • 强制查找依赖项,例如,仅提供
    byId()
    操作
    • 需要大量非面向对象的例程,例如,
      findzzbyid(zid)
      ,然后
      getYyyIds(zid)
      而不是
      z.getY()
    • 如果事务之间存在较大的处理开销,则逐个获取集合中的每个对象可能很有用
  • 使应用程序成为@Transactional的一部分,而不仅仅是
    • 嵌套事务的可能考虑事项
    • 需要适应事务管理的例程(例如,足够小)
    • 编程影响小,但可能导致大型事务
  • 为DAO提供动态的,例如,
    loadData(id,fetchProfile)
    
    • 应用程序必须知道何时使用哪个配置文件
  • AoP类型的事务,例如,在必要时拦截操作并执行事务
    • 需要字节码操作或代理使用
    • 执行交易时失去控制
    • 黑魔法,一如既往:)
  • 我错过了任何选择吗


    在您的应用程序设计中尝试最小化
    延迟加载关系的影响时,您首选哪种方法


    (哦,很抱歉)

    一种非常常见的模式是在构建web应用程序时使用

    如果您正在构建一个服务,我会在服务的公共方法上打开TX,而不是在DAO上,因为一个方法通常需要获取或更新多个实体

    这将解决任何“延迟加载异常”。如果您需要更高级的性能调优工具,我认为获取配置文件是一个不错的选择

    众所周知,hibernate尽可能做到非侵入性和透明

    我认为最初的假设是错误的。父持久性是一个神话,因为应用程序始终应该考虑实体生命周期和加载的对象图的大小

    请注意,Hibernate无法读取想法,因此,如果您知道特定操作需要一组特定的依赖项,则需要以某种方式表达您的休眠意图


    从这个角度来看,明确表达这些意图(即2、4和7)的解决方案看起来是合理的,并且不会因缺乏透明度而受损。

    我不确定您指的是哪个问题(由懒散引起),但对我来说,最大的痛苦是避免在我自己的应用程序缓存中丢失会话上下文。典型案例:

    • 对象
      foo
      加载并放入地图
    • 另一个线程从映射中获取这个对象,并调用
      foo.getBar()
      (以前从未调用过并且是惰性计算的)
    因此,为了解决这个问题,我们有一些规则:

    • 尽可能透明地包装会话(例如,对于Web应用程序,
      OpenSessionInViewFilter
    • 为线程/线程池提供公共API,其中db会话绑定/取消绑定在层次结构的某个较高位置(包装在
      try/finally
      中),这样子类就不必考虑它
    • 在线程之间传递对象时,传递ID而不是对象本身。如果需要,接收线程可以加载对象
    • 缓存对象时,绝不缓存对象,而是缓存其ID。在您的DAO或manager类中有一个抽象方法,在您知道ID的情况下从二级Hibernate缓存加载对象。从二级Hibernate缓存检索对象的成本仍然比到DB便宜得多

    正如你所看到的,这确实远不及非侵入性和透明性。但是,与我为迫不及待的装载而付出的代价相比,成本仍然可以承受。后者的问题是,在加载单个引用对象时,有时会导致蝴蝶效应,更不用说实体集合了。内存消耗、CPU使用率和延迟也要差得多,所以我想我可以接受。

    你说得对,当然,尽可能透明的方法目前为止只能起作用。这些都是你想要的不错的选择。伊莫:答案完全正确。事实上,这是一个神话。顺便说一句:我会投票支持选项4和7(或者完全不使用ORM)