使用Wicket + Spring + Hibernate的三层分层应用程序。 你会如何处理交易?

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

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

对于如何使用Hibernate和Spring将这种解决方案与三层架构集成,我是否有某种最佳实践(因为我认为我决定使用Wicket进行演示应该不重要)?

如果我使用OSIV,我将至少永远不会遇到延迟加载exception,另一方面,我的事务将更长寿,然后才能通过在视图中未提交来提交。

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

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

OTOH您将不得不考虑更多关于您在服务中所做的事情(延迟加载,如果需要共同的事务性,则使用相同的服务方法对function进行分组等等)。

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

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

如果我使用OSIV,我至少会遇到延迟加载exception

这不是真的,事实上它非常容易遇到臭名昭着的LazyInitializationException,只是加载一个对象,并尝试在视图之后读取它的一个属性,这取决于你将获得LIE的配置