General ORM Integration Considerations

Spring ORM 集成旨在简化应用程序分层和模块间的松散耦合。它提供了一致的方法来连接应用程序对象,并通过模板和 AOP 拦截器实现适当的资源和事务管理。通过异常转换,可以使用纯持久技术 API 实现 DAO,同时仍然受益于 Spring 的依赖注入、事务支持和自定义异常层次结构。

本节重点介绍适用于所有 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, previous section 中提到的 JdbcTemplate 类提供了连接处理和 SQLExceptionDataAccessException 层次结构的适当转换,包括将特定于数据库的 SQL 错误代码转换为有意义的异常类。有关如何获得相同异常转换优势的信息,请参阅 ORM 技术的 next section

JdbcTemplate 类与 Springtransaction 支持相结合,并且通过各个Spring 事务管理器支持 JTA 和 JDBC 事务。对于所支持的 ORM 技术,Spring 提供了 Hibernate 和 JPA 支持以及 JTA 支持,方法是通过 Hibernate 和 JPA 事务管理器。有关事务支持的详细信息,请参阅 Transaction Management 章节。

Exception Translation

当你已经在 DAO 中使用 Hibernate 或 JPA 时,你必须决定如何处理持久化技术的原生异常类。DAO 根据技术抛出一个 HibernateExceptionPersistenceException 的子类。这些异常都是运行时异常,并且不必声明或捕获。你可能还必须处理 IllegalArgumentExceptionIllegalStateException。这意味着调用者只能将异常视为通常是致命的,除非他们想要依赖持久化技术的异常结构本身。在不将调用者与实现策略捆绑在一起的情况下,是不可能捕获具体原因(例如,乐观锁失败)的。对于强烈基于 ORM 或不需要任何特殊异常处理(或两者兼而有之)的应用程序,这种权衡可能是可以接受的。然而,Spring 可以通过 @Repository 注释透明地应用异常转换。以下示例(一个适用于 Java 配置,一个适用于 XML 配置)展示了如何执行此操作:

  • Java

  • Kotlin

@Repository
public class ProductDaoImpl implements ProductDao {

	// class body here...

}
@Repository
class ProductDaoImpl : ProductDao {

	// class body here...

}
<beans>

	<!-- Exception translation bean post processor -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

	<bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

后处理器自动查找所有异常转换器(PersistenceExceptionTranslator 接口的实现),并指示使用 @Repository 注释标记的所有 bean,以便发现的转换器可以拦截抛出的异常并在其上应用适当的转换。

总结来说,你可以使用纯持久技术 API 和注释来实现 DAO,同时还可以利用 Spring 管理的事务、依赖注入和透明异常转换(如果需要),转换为 Spring 的自定义异常层次结构。