Hibernate懒加载应用程序设计
Hibernate懒加载应用程序设计
我倾向于在应用中使用Hibernate和Spring框架的组合,利用Spring的声明式事务划分能力(例如,@Transactional)。众所周知,Hibernate试图尽可能地无侵入和透明,然而在使用延迟加载关系时,这变得有些具有挑战性。
我看到了几种不同透明度级别的设计选择:
1. 不使用延迟加载的关系(例如,fetchType=FetchType.EAGER)
- 这违背了延迟加载的整体思想…
2. 使用Hibernate.initialize(proxyObj)初始化集合
- 这意味着与DAO耦合性较高
- 虽然我们可以定义一个带有initialize的接口,但不能保证其他实现提供任何等效功能。
3. 将事务行为添加到持久化的Model对象本身(使用动态代理或@Transactional)
- 我从未尝试过动态代理方法,虽然在持久对象本身上似乎无法使@Transactional工作。可能是因为Hibernate首先操作的是代理对象。
- 失去了对事务实际发生的控制
4. 提供延迟加载和非延迟加载的API,例如loadData()和loadDataWithDeps()
- 强制应用程序知道何时使用哪个例程,再次紧密耦合
- 方法过载,loadDataWithA(),....,loadDataWithX()
5. 强制查找依赖项,例如只提供byId()操作
- 需要很多非面向对象的例程,例如findZzzById(zid),然后getYyyIds(zid)而不是z.getY()
- 如果事务之间存在大量处理开销,逐个获取集合中的每个对象可能很有用。
6. 使应用程序的一部分成为@Transactional,而不仅仅是DAO
- 可能需要嵌套事务的考虑
- 需要为事务管理适应的例程(例如,足够小)
- 编程影响小,尽管可能导致大事务
7. 为DAO提供动态的获取配置文件,例如loadData(id, fetchProfile)
- 应用程序必须知道何时使用哪个配置文件
8. AoP类型的事务,例如拦截操作并在必要时执行事务
- 需要字节码操作或代理使用
- 在执行事务时失去了控制
- 一如既往的黑魔法
我漏掉了哪个选项吗?
在尝试减少应用程序设计中延迟加载关系的影响时,您更喜欢哪种方法?
(哦,对于长篇文字道歉)