3

我正在考虑使用 Spring 附带的Open Session In View (OSIV)过滤器或拦截器,因为这对我作为开发人员来说似乎是一种方便的方式。如果这是你推荐的,你推荐使用过滤器还是拦截器,为什么?

我还想知道它将如何与HibernateTemplate混合,以及我是否会失去将方法标记为@Transactional(readOnly = true)等的能力,从而失去获得更细粒度事务控制的能力?

是否有某种最佳实践可以将这种解决方案与使用 Hibernate 和 Spring 的三层架构集成(因为我认为我决定使用 Wicket 进行演示应该无关紧要)?

如果我使用 OSIV,我至少永远不会遇到延迟加载异常,另一方面,我的事务将在能够通过在视图中未提交来提交之前存活更长的时间。

4

2 回答 2

4

这真的是个人品味的问题。

就个人而言,我喜欢在服务层设置事务边界。如果您开始考虑 SOA,那么对服务的每次调用都应该是独立的。如果您的视图层必须调用 2 个不同的服务(我们可以说这已经是代码异味),那么这 2 个服务应该彼此独立运行,可能有不同的事务配置,等等......没有事务在外部打开services 还有助于确保在服务之外不会发生任何修改。

OTOH,您将不得不更多地考虑您在服务中所做的事情(延迟加载,如果需要共同的事务性,则在同一服务方法中对功能进行分组等......)。

一种有助于减少延迟加载错误的模式是在服务层之外使用值对象。服务应始终加载所需的所有数据并将其复制到 VO。您失去了持久对象和视图层之间的直接映射(这意味着您必须编写更多代码),但您可能会发现您变得更加清晰......

编辑:这个决定将基于权衡,所以我仍然认为这至少部分是个人品味的问题。服务层的事务对我来说感觉更干净(更像 SOA,逻辑明确限制在服务层,不同的调用明确分离,...)。这种方法的问题是 LazyLoadingExceptions,可以通过使用 VO 来解决。如果 VO 只是您的持久对象的副本,那么是的,这显然是对 DRY 原则的破坏。如果您像使用数据库视图一样使用 VO,那么 VO 就是对持久对象的简化。仍然需要编写更多代码,但它会让你的设计更清晰。如果您需要插入一些授权方案,这将变得特别有用:如果某些字段仅对某些角色可见,

于 2009-02-10T10:09:21.130 回答
2

如果我使用 OSIV,我至少永远不会遇到延迟加载异常

这不是真的,实际上它非常容易遇到臭名昭著的 LazyInitializationException,只需加载一个对象,并尝试读取它的属性,查看后,根据您的配置,您将得到 LIE

于 2009-02-10T09:53:38.750 回答