【发布时间】:2011-06-28 23:02:54
【问题描述】:
我倾向于将Hibernate 与Spring 框架结合使用,它具有声明性事务划分功能(例如@Transactional)。
众所周知,hibernate 尝试尽可能地非侵入性和透明,但这证明更具挑战性在使用 lazy-loaded 关系时。
我看到了许多具有不同透明度的设计替代方案。
- 使关系不延迟加载(例如,
fetchType=FetchType.EAGER)- 这违反了延迟加载的整个想法..
- 使用
Hibernate.initialize(proxyObj);初始化集合- 这意味着与 DAO 的耦合度相对较高
- 虽然我们可以用
initialize定义一个接口,但不能保证其他实现提供任何等价物。
- 将事务行为添加到持久化
Model对象本身(使用dynamic proxy 或@Transactional)- 我没有尝试过动态代理方法,尽管我似乎从来没有让@Transactional 处理持久对象本身。可能是由于休眠是在代理上的操作。
- 在交易实际发生时失去控制
- 同时提供惰性/非惰性 API,例如
loadData()和loadDataWithDeps()- 强制应用程序知道何时使用哪个例程,再次紧密耦合
- 方法溢出,
loadDataWithA(),....,loadDataWithX()
- 强制查找依赖项,例如,仅提供
byId()操作- 需要大量非面向对象的例程,例如
findZzzById(zid),然后是getYyyIds(zid)而不是z.getY() - 如果事务之间的处理开销很大,则一个接一个地获取集合中的每个对象会很有用。
- 需要大量非面向对象的例程,例如
- 加入应用程序 @Transactional 而不仅仅是DAO
- 嵌套事务的可能考虑因素
- 需要适应事务管理的例程(例如,足够小)
- 程序影响小,但可能会导致大量交易
- 为DAO提供动态fetch profiles,例如
loadData(id, fetchProfile);- 应用程序必须知道何时使用哪个配置文件
- AoP 类型的事务,例如,拦截操作并在必要时执行事务
- 需要字节码操作或使用代理
- 执行事务时失去控制
- 黑魔法,一如既往:)
我错过了任何选项吗?
在尝试将lazy-loaded 关系在您的应用程序设计中的影响降至最低时,您首选哪种方法?
(哦,对不起WoT)
【问题讨论】:
-
选项 2 和 5 的示例:m-hewedy.blogspot.ch/2010/03/…
-
能否请您提供选项 4 的示例?
标签: java hibernate spring lazy-loading application-design