Hibernate延迟加载应用程序设计 [英] Hibernate lazy-load application design
问题描述
我倾向于将 Hibernate 与 Spring 框架,它是声明式的事务分界功能(例如, @事务)。
大家都知道,hibernate会尽可能地保持非侵入性和透明性,在使用 lazy-loaded
关系时证明更具挑战性。
我看到许多具有不同透明度级别的设计方案。
- 使关系不会延迟加载(例如,
fetchType = FetchType.EAGER)
- 这违背了延迟加载的整个想法。
- 使用初始化集合
Hibernate.initialize(proxyObj);
- 这意味着与DAO的耦合度相对较高
- 虽然我们可以使用
initialize
定义接口,但是其他实现不能保证提供任何等价的功能。
- 这意味着与DAO的耦合度相对较高
- 将交易行为添加到持续
模型
对象本身(使用动态代理或@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 - Make relationships not lazy-loaded (e.g.,
fetchType=FetchType.EAGER)
- This vioalites the entire idea of lazy loading ..
- 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.
- 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
- Provide both lazy/non-lazy API, e.g,
loadData()
andloadDataWithDeps()
- Forces the application to know when to employ which routine, again tight coupling
- Method overflow,
loadDataWithA()
, ....,loadDataWithX()
- Force lookup for dependencies, e.g., by only providing
byId()
operations- Requires alot of non-object oriented routines, e.g.,
findZzzById(zid)
, and thengetYyyIds(zid)
instead ofz.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.
- Requires alot of non-object oriented routines, e.g.,
- 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
- Provide the DAO with dynamic fetch profiles, e.g.,
loadData(id, fetchProfile);
- Applications must know which profile to use when
- 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 :)
在您的应用程序设计中尝试最小化
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.
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屋!