休眠延迟加载应用程序设计
2022-08-31 11:46:29
我倾向于将Hibernate与Spring框架及其声明性事务划分功能(例如,@Transactional)结合使用。
众所周知,休眠试图尽可能地非侵入性和透明性,但是在使用懒惰加载
的关系时,这被证明是更具挑战性的。
我看到许多具有不同透明度的设计选择。
- 使关系不延迟加载(例如,
fetchType=FetchType.EAGER)
- 这破坏了延迟加载的整个想法..
- 使用
Hibernate.initialize(proxyObj);
- 这意味着与DAO的耦合相对较高
- 虽然我们可以用 定义一个接口,但不能保证其他实现提供任何等价物。
initialize
- 将事务行为添加到持久性对象本身(使用动态代理或
Model
@Transactional
)- 我没有尝试过动态代理方法,尽管我似乎从未@Transactional处理持久对象本身。可能是由于休眠是在代理上进行操作。
- 当交易实际发生时失去控制
- 提供懒惰/非懒惰的API,例如,和
loadData()
loadDataWithDeps()
- 强制应用程序知道何时使用哪个例程,再次紧密耦合
- 方法溢出, , ....,
loadDataWithA()
loadDataWithX()
- 强制查找依赖关系,例如,仅通过提供操作
byId()
- 需要大量的非面向对象的例程,例如,,然后代替
findZzzById(zid)
getYyyIds(zid)
z.getY()
- 如果事务之间存在较大的处理开销,则逐个获取集合中的每个对象会很有用。
- 需要大量的非面向对象的例程,例如,,然后代替
- 使应用程序的一部分@Transactional而不仅仅是 DAO
- 嵌套事务的可能注意事项
- 需要适合事务管理的例程(例如,足够小)
- 较小的编程影响,尽管可能导致较大的事务
- 为 DAO 提供动态抓取配置文件,例如:
loadData(id, fetchProfile);
- 应用程序必须知道在以下情况下要使用哪个配置文件
- AoP 类型的事务,例如,拦截操作并在必要时执行事务
- 需要字节码操作或代理使用
- 执行事务时失去控制
- 黑魔法,一如既往:)
我错过了任何选项吗?
在尝试在应用程序设计中最大程度地减少关系的影响时,您首选哪种方法?lazy-loaded
(哦,对不起WoT)