General ORM Integration Considerations

本节强调了适用于所有 ORM 技术的注意事项。Hibernate 部分提供了更多的细节,也在一个具体的环境中展示了这些特性和配置。

Spring 的 ORM 集成的主要目标是 清晰的应用分层(与任何数据访问和事务技术)和 应用对象的松散耦合 ,不再有业务服务对数据访问或事务策略的依赖,不再有硬编码的资源查找,不再有难以替换的单例,不再有自定义的服务注册表。我们的目标是用一种简单的、一致的方法来连接应用对象,使它们尽可能地保持可重复使用,并且不受容器依赖的影响。所有单独的数据访问功能都可以单独使用,但与 Spring 的应用上下文概念很好地整合在一起,提供基于 XML 的配置和无需 Spring 感知的普通 JavaBean 实例的交叉引用。在一个典型的 Spring 应用程序中,许多重要的对象都是 JavaBean:数据访问模板、数据访问对象、事务管理器、使用数据访问对象和事务管理器的业务服务、Web 视图解析器、使用业务服务的 Web 控制器,等等。

资源和事务管理

Resource and Transaction Management

典型的商业应用被重复的资源管理代码弄得一团糟。许多项目试图发明他们自己的解决方案,有时为了编程的方便而牺牲了对失败的正确处理。Spring 提倡简单的解决方案,即在 JDBC 的情况下,通过模板化实现 IoC,并为 ORM 技术应用 AOP 拦截器。

基础设施提供了适当的资源处理,并将特定的 API 异常适当转换为未检查的基础设施异常层次。Spring 引入了一个 DAO 异常层次结构,适用于任何数据访问策略。对于直接的 JDBC,上一节提到的 JdbcTemplate 类提供了连接处理和 SQLException 到 DataAccessException 层次结构的适当转换,包括将数据库特定的 SQL 错误代码转换为有意义的异常类别。对于 ORM 技术,请参阅下一节,了解如何获得同样的异常转换优势。

说到事务管理,JdbcTemplate 类与 Spring 事务支持挂钩,通过各自的 Spring 事务管理器,支持 JTA 和 JDBC 事务。对于支持的 ORM 技术,Spring 通过 Hibernate 和 JPA 事务管理器提供 Hibernate 和 JPA 支持,以及 JTA 支持。关于事务支持的细节,请参见事务管理章节

异常翻译

Exception Translation

当你在 DAO 中使用 Hibernate 或 JPA 时,你必须决定如何处理持久化技术的本地异常类。DAO 会抛出 HibernateException 或 PersistenceException 的子类,具体取决于技术。这些异常都是运行时异常,不需要声明或捕获。你可能还需要处理 IllegalArgumentException 和 IllegalStateException。这意味着调用者只能将异常视为一般致命的,除非他们想依赖持久化技术自己的异常结构。如果不把调用者与实现策略绑在一起,就不可能捕捉到特定的原因(比如乐观的锁定失败)。这种权衡对于那些强烈基于 ORM 或不需要任何特殊异常处理(或两者)的应用来说,可能是可以接受的。然而,Spring 允许通过 @Repository注解透明地应用异常转换。下面的例子(一个用于 Java 配置,一个用于 XML 配置)展示了如何做到这一点:

  1. @Repository
  2. public class ProductDaoImpl implements ProductDao {
  3. // class body here...
  4. }
  1. <beans>
  2. <!-- 异常翻译的后置处理器 -->
  3. <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
  4. <bean id="myProductDao" class="product.ProductDaoImpl"/>
  5. </beans>

后处理器会自动寻找所有的异常翻译器(PersistenceExceptionTranslator 接口的实现),并告知所有标有 @Repository注解的 Bean,以便被发现的翻译器能够拦截并对抛出的异常应用适当的翻译。

总之,你可以基于普通持久化技术的 API 和注解来实现 DAO,同时还可以从 Spring 管理的事务、依赖注入和透明的异常转换(如果需要的话)中受益于 Spring 的自定义异常层次结构。