Hibernate延迟加载应用程序设计 [英] Hibernate lazy-load application design

查看:188
本文介绍了Hibernate延迟加载应用程序设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我倾向于将 Hibernate Spring 框架,它是声明式的事务分界功能(例如, @事务)。

大家都知道,hibernate会尽可能地保持非侵入性和透明性,在使用 lazy-loaded 关系时证明更具挑战性




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


  1. 使关系不会延迟加载(例如, fetchType = FetchType.EAGER)

    • 这违背了延迟加载的整个想法。


    • 使用初始化集合 Hibernate.initialize(proxyObj);

      • 这意味着与DAO的耦合度相对较高
      • 虽然我们可以使用 initialize 定义接口,但是其他实现不能保证提供任何等价的功能。


      • 将交易行为添加到持续模型对象本身(使用动态代理 @Transactional

        • 我还没有尝试动态代理方法,尽管我似乎并没有让@Transactional自己处理持久对象。可能是由于hibernate是在代理上运行的。

        • 提供懒惰/非懒惰API,例如 loadData() loadDataWithDeps()

          • 强制应用程序知道何时使用哪个例程,再次紧密耦合

          • 方法溢出, loadDataWithA(),.... , loadDataWithX()


        • 强制查找依赖项,例如, byId()操作

          • 需要大量非面向对象的例程,例如 findZzzById zid),然后 getYyyIds(zid)而不是 z.getY()

          • 如果事务之间存在大量的处理开销,那么逐个获取集合中的每个对象会非常有用。


        • 构成应用程序的一部分 @Transactional而不仅仅是DAO

          • 嵌套交易的可能考虑因素

          • 需要适用于交易管理(例如,足够小)

          • 尽管可能导致大量交易,但程序设计上的小影响


        • 使用动态获取配置文件来提供DAO,例如 loadData(id,fetchProfile);



          • AoP类型的事务,例如拦截操作并在必要时执行事务

            • 需要字节码操作或代理使用
            • li>
            • 执行交易时失去控制权

            • 一如既往的黑魔法:)



            • $ b

              我错过了任何选项吗?





              $ b

              在您的应用程序设计中尝试最小化 lazy-loaded 关系的影响时,您首选哪种方法?



              (哦,对不起 WoT

              解决方案


              众所周知,hibernate试图成为非侵入式并尽可能透明


              我会说最初的假设是错误的。 Transaparent持久化是一个神话,因为应用程序总是应该处理实体生命周期和正在加载的对象图的大小。

              注意,Hibernate不能读取想法,因此如果你知道你需要一组特定操作的依赖关系,你需要以某种方式表达你对Hibernate的意图。



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


              I tend to use Hibernate in combination with Spring framework and it's declarative transaction demarcation capabilities (e.g., @Transactional).

              As we all known, hibernate tries to be as non-invasive and as transparent as possible, however this proves a bit more challenging when employing lazy-loaded relationships.


              I see a number of design alternatives with different levels of transparency.

              1. Make relationships not lazy-loaded (e.g., fetchType=FetchType.EAGER)
                • This vioalites the entire idea of lazy loading ..
              2. Initialize collections using Hibernate.initialize(proxyObj);
                • This implies relatively high-coupling to the DAO
                • Although we can define an interface with initialize, other implementations are not guaranteed to provide any equivalent.
              3. Add transaction behaviour to the persistent Model objects themselves (using either dynamic proxy or @Transactional)
                • I've not tried the dynamic proxy approach, although I never seemed to get @Transactional working on the persistent objects themselves. Probably due to that hibernate is operation on a proxy to bein with.
                • Loss of control when transactions are actually taking place
              4. Provide both lazy/non-lazy API, e.g, loadData() and loadDataWithDeps()
                • Forces the application to know when to employ which routine, again tight coupling
                • Method overflow, loadDataWithA(), ...., loadDataWithX()
              5. Force lookup for dependencies, e.g., by only providing byId() operations
                • Requires alot of non-object oriented routines, e.g., findZzzById(zid), and then getYyyIds(zid) instead of z.getY()
                • It can be useful to fetch each object in a collection one-by-one if there's a large processing overhead between the transactions.
              6. Make part of the application @Transactional instead of only the DAO
                • Possible considerations of nested transactions
                • Requires routines adapted for transaction management (e.g., suffiently small)
                • Small programmatic impact, although might result in large transactions
              7. Provide the DAO with dynamic fetch profiles, e.g., loadData(id, fetchProfile);
                • Applications must know which profile to use when
              8. AoP type of transactions, e.g., intercept operations and perform transactions when necessary
                • Requires byte-code manipulation or proxy usage
                • Loss of control when transactions are performed
                • Black magic, as always :)

              Did I miss any option?


              Which is your preferred approach when trying to minimize the impact of lazy-loaded relationships in your application design?

              (Oh, and sorry for WoT)

              解决方案

              As we all known, hibernate tries to be as non-invasive and as transparent as possible

              I would say the initial assumption is wrong. Transaparent persistence is a myth, since application always should take care of entity lifecycle and of size of object graph being loaded.

              Note that Hibernate can't read thoughts, therefore if you know that you need a particular set of dependencies for a particular operation, you need to express your intentions to Hibernate somehow.

              From this point of view, solutions that express these intentions explicitly (namely, 2, 4 and 7) look reasonable and don't suffer from the lack of transparency.

              这篇关于Hibernate延迟加载应用程序设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆