我倾向于将Hibernate与Spring框架结合使用,它具有声明式事务划分功能(例如@Transactional)。
众所周知,休眠试图尽可能做到非侵入性和透明性,但是事实证明,在使用关系时这更具挑战性lazy-loaded
。
我看到了许多具有不同透明度的设计方案。
- 使关系不延迟加载(例如,
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)