通用 ORM 集成注意事项 (General ORM Integration Considerations)
本节重点介绍适用于所有 ORM 技术的集成注意事项。Spring ORM 集成的主要目标是实现清晰的应用分层(无论使用何种数据访问和事务技术)以及应用对象的松耦合。
资源和事务管理
典型的业务应用往往充斥着重复的资源管理代码。Spring 为资源处理提供了简单的解决方案:通过 IoC 实现。
- 资源处理:Spring 的基础设施提供了适当的资源处理方式,并将特定 API 的异常转换为无状态的基础设施异常体系(
DataAccessException)。 - 事务分层:对于 JDBC,
JdbcTemplate挂钩到 Spring 事务支持;对于 ORM,Spring 通过HibernateTransactionManager或JpaTransactionManager提供支持,同时也支持 JTA。
异常翻译
当你使用 Hibernate 或 JPA 时,必须决定如何处理该技术原生的受检或非受检异常。DAO 通常会抛出 HibernateException 或 PersistenceException。
如果调用者不想依赖于特定持久化技术的异常结构,捕获特定原因(如乐观锁失败)将非常困难。Spring 通过 @Repository 注解提供了透明的异常翻译功能。
如何启用异常翻译
在 DAO 类上添加注解:
java@Repository public class ProductDaoImpl implements ProductDao { // ... }kotlin@Repository class ProductDaoImpl : ProductDao { // ... }注册翻译处理器: 在配置中定义
PersistenceExceptionTranslationPostProcessor:xml<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>或者在 Java 配置中通过
@Bean定义该后置处理器。
工作原理
该后置处理器会自动寻找所有异常翻译器(PersistenceExceptionTranslator 接口的实现),并对所有带有 @Repository 注解的 Bean 应用切面(Advisor),拦截并翻译抛出的异常。
补充教学
1. 深度解析 @Repository 的双重身份
在 Spring 中,@Repository 不仅仅是一个表示“我是 DAO 层”的语义化注解(类似 @Service 或 @Controller),它还带有一个功能性魔法:
- 语义标识:让组件扫描(Component Scanning)自动发现它。
- 异常翻译开关:它是
PersistenceExceptionTranslationPostProcessor的目标指示器。如果没有这个注解,即使你配置了处理器,底层的 JPA 或 Hibernate 异常也不会被翻译成 Spring 的DataAccessException。
2. 为什么异常翻译如此重要?
想象一下你的业务 Service 层:
try {
dao.save(product);
} catch (DataIntegrityViolationException e) {
// 这是一个通用的 Spring 异常
// 即使你明天把 JPA 换成 JDBC,这个 catch 块依然有效
}如果没有异常翻译,你必须 catch javax.persistence.EntityExistsException 或 org.hibernate.exception.ConstraintViolationException。一旦你更换了持久化框架,你的业务层代码就会发生大面积崩溃。Spring 的翻译机制保护了业务逻辑的架构独立性。
3. 事务的“跨界”能力
Spring 的 ORM 集成允许你在同一个事务中混合使用不同的技术。 例如,你可以使用 JPA 处理复杂的对象映射,同时使用 JdbcTemplate 执行一些复杂的原生 SQL 或批处理。只要它们使用相同的 DataSource,并且你配置了正确的 JpaTransactionManager,它们就会自动参与到同一个底层数据库事务中。这是 Spring 对企业级应用最强大的支持之一。