16.2 集成ORM的注意事项

本节重点介绍适用于所有集成ORM技术的注意事项。在16.3Hibernate一节中提供了很多关于如何配置和使用这些特性提的信息。

Spring对ORM集成的主要目的是使应用层次化,可以任意选择数据访问和事务管理技术,并且为应用对象提供松耦合结构。不再将业务逻辑依赖于数据访问或者事务策略上,不再使用基于硬编码的资源查找,不再使用难以替代的单例,不再自定义服务的注册。同时,为应用提供一个简单和一致的方法来装载对象,保证他们的重用并且尽可能不依赖于容器。所有单独的数据访问功能都可以自己使用,也可以很好地与Spring的ApplicationContext集成,提供基于XML的配置和不需要Spring感知的普通JavaBean实例。在典型的Spring应用程序中,许多重要的对象都是JavaBean:数据访问模板,数据访问对象,事务管理器,使用数据访问对象和事务管理器的业务服务,Web视图解析器,使用业务服务的Web控制器等等。

16.2.1 资源和事务管理

通常企业应用都会包含很多重复的的资源管理代码。很多项目总是尝试去创造自己的解决方案,有时会为了开发的方便而牺牲对错误的处理。Spring为资源的配置管理提供了简单易用的解决方案,在JDBC上使用模板技术,在ORM上使用AOP拦截技术。

Spring的基础设施提供了合适的资源处理,同时Spring引入了DAO层的异常体系,可以适用于任何数据访问策略。对于JDBC直连来说,前面提及到的JdbcTemplate类提供了包括连接处理,对SQLExceptionDataAccessException的异常封装,同时还包含对于一些特定数据库SQL错误代码的转换。对于ORM技术来说,可以参考下一节来了解异常封装的优点。

当谈到事务管理时,JdbcTemplate类通过Spring事务管理器挂接到Spring事务支持,并支持JTA和JDBC事务。Spring通过Hibernate,JPA事务管理器和JTA的支持来提供Hibernate和JPA这类ORM技术的支持。想了解更多关于事务的描述,可以参考第13章,事务管理

16.2.2 异常转义

当在DAO层中使用Hibernate或者JPA的时候,开发者必须决定该如何处理持久化技术的一些原生异常。DAO层会根据选择技术的不同而抛出HibernateException或者PersistenceException。这些异常都属于运行时异常,所以无需显式声明和捕捉。同时,开发者同时还需要处理IllegalArgumentExceptionIllegalStateException这类异常。一般情况下,调用方通常只能将这一类异常视为致命的异常,除非他们想要自己的应用依赖于持久性技术原生的异常体系。如果需要捕获一些特定的错误,比如乐观锁获取失败一类的错误,只能选择调用方和实现策略耦合到一起。对于那些只基于某种特定ORM技术或者不需要特殊异常处理的应用来说,使用ORM本身的异常体系的代价是可以接受的。但是,Spring可以通过@Repository注解透明地应用异常转换,以解耦调用方和ORM技术的耦合:

  1. @Repository
  2. public class ProductDaoImpl implements ProductDao {
  3. // class body here...
  4. }
  1. <beans>
  2. <!-- Exception translation bean post processor -->
  3. <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
  4. <bean id="myProductDao" class="product.ProductDaoImpl"/>
  5. </beans>

上面的后置处理器PersistenceExceptionTranslationPostProcessor,会自动查找所有的异常转义器(实现PersistenceExceptionTranslator接口的Bean),并且拦截所有标记为@Repository注解的Bean,通过代理来拦截异常,然后通过PersistenceExceptionTranslator将DAO层异常转义后的异常抛出。

总而言之:开发者可以既基于简单的持久化技术的API和注解来实现DAO,同时还受益于Spring管理的事务,依赖注入和透明异常转换(如果需要)到Spring的自定义异常层次结构。