我倾向于把Hibernate与Spring框架结合使用,并利用其声明式事务划分能力(例如,@Transactional)。
众所周知,Hibernate试图尽可能地保持“非侵入性”和“透明性”,但是在使用“延迟加载”关系时,这变得有点更具挑战性。
我看到了许多设计方案,其中各种透明级别不同。
- 使关系不延迟加载 (例如,
fetchType=FetchType.EAGER)
- 这违反了懒加载的整个理念..
- 使用
Hibernate.initialize(proxyObj);
初始化集合- 这意味着与DAO相对较高的耦合
- 尽管我们可以定义一个带有
initialize
的接口,但不能保证其他实现提供任何等效内容。
- 将事务行为添加到持久
Model
对象本身上(使用动态代理或@Transactional
)- 我从未尝试过动态代理方法,虽然我似乎从未让@Transactional在持久对象本身上工作。可能是因为Hibernate实际上正在操作一个代理。
- 失去了控制事务实际的进行时机
- 提供懒/非懒API,例如,
loadData()
和loadDataWithDeps()
- 强制应用程序知道何时采用哪个例程,再次紧密耦合
- 方法溢出,
loadDataWithA()
, ....,loadDataWithX()
- 强制查找依赖项,例如仅提供
byId()
操作- 需要很多非面向对象的例程,例如
findZzzById(zid)
,然后是getYyyIds(zid)
而不是z.getY()
- 如果在事务之间存在大量处理开销,则逐个获取集合中的每个对象可能很有用。
- 需要很多非面向对象的例程,例如
- 将部分应用程序@Transactional而不仅仅是DAO
- 可能考虑嵌套事务
- 需要适应事务管理的例程(例如足够小)
- 对程序影响较小,尽管可能导致大型交易
- 为DAO提供动态提取配置文件,例如
loadData(id,fetchProfile);
- 应用程序必须知道何时使用哪个配置文件
- AoP类型的事务,例如拦截操作并在必要时执行事务
- 需要字节码操作或代理使用
- 在执行事务时失去控制
- 黑魔法,一如既往 :)
我有错过任何选项吗?
在尝试最小化应用程序设计中lazy-loaded
关系的影响时,您更喜欢哪种方法?
(噢,对于 WoT 很抱歉)