General ORM Integration Considerations
Spring ORM 集成旨在简化应用程序分层和模块间的松散耦合。它提供了一致的方法来连接应用程序对象,并通过模板和 AOP 拦截器实现适当的资源和事务管理。通过异常转换,可以使用纯持久技术 API 实现 DAO,同时仍然受益于 Spring 的依赖注入、事务支持和自定义异常层次结构。
本节重点介绍适用于所有 ORM 技术的注意事项。Hibernate 部分提供更多详细信息,并在具体上下文中展示了这些功能和配置。
This section highlights considerations that apply to all ORM technologies. The Hibernate section provides more details and also show these features and configurations in a concrete context.
Spring ORM 集成的主要目的是清晰的应用程序分层(使用任何数据访问和事务技术)以及应用程序对象的松散耦合——业务服务不再依赖数据访问或事务策略,不再需要写死的资源查找,不再需要难以替换的单例,也不再需要自定义服务注册表。目标是使用一种简单而一致的方法来连接应用程序对象,在尽可能不依赖于容器的情况下保持它们的可重用和自由。所有单个数据访问特性都是可以单独使用的,但与 Spring 的应用程序上下文概念整合得很好,提供了基于 XML 的配置,以及无需 Spring 感知即可相互引用的纯 JavaBean 实例。在典型的 Spring 应用程序中,许多重要对象都是 JavaBean:数据访问模板、数据访问对象、事务管理器、使用数据访问对象和事务管理器的业务服务、web 视图解析器、使用业务服务的 web 控制器,等等。
The major goal of Spring’s ORM integration is clear application layering (with any data access and transaction technology) and for loose coupling of application objects — no more business service dependencies on the data access or transaction strategy, no more hard-coded resource lookups, no more hard-to-replace singletons, no more custom service registries. The goal is to have one simple and consistent approach to wiring up application objects, keeping them as reusable and free from container dependencies as possible. All the individual data access features are usable on their own but integrate nicely with Spring’s application context concept, providing XML-based configuration and cross-referencing of plain JavaBean instances that need not be Spring-aware. In a typical Spring application, many important objects are JavaBeans: data access templates, data access objects, transaction managers, business services that use the data access objects and transaction managers, web view resolvers, web controllers that use the business services, and so on.
Resource and Transaction Management
典型的业务应用程序中充斥着重复的资源管理代码。许多项目尝试创造自己的解决方案,有时会为了编程便利性而牺牲对故障的适当处理。Spring 主张使用简单的解决方案来实现适当的资源处理,即 JDBC 中通过模板实现 IoC,以及为 ORM 技术应用 AOP 拦截器。
Typical business applications are cluttered with repetitive resource management code. Many projects try to invent their own solutions, sometimes sacrificing proper handling of failures for programming convenience. Spring advocates simple solutions for proper resource handling, namely IoC through templating in the case of JDBC and applying AOP interceptors for the ORM technologies.
该基础设施提供适当的资源处理和特定 API 异常到未经检查的基础设施异常层次结构的适当转换。Spring 引入了一个 DAO 异常层次结构,适用于任何数据访问策略。对于直接 JDBC, previous section 中提到的 JdbcTemplate
类提供了连接处理和 SQLException
到 DataAccessException
层次结构的适当转换,包括将特定于数据库的 SQL 错误代码转换为有意义的异常类。有关如何获得相同异常转换优势的信息,请参阅 ORM 技术的 next section。
The infrastructure provides proper resource handling and appropriate conversion of
specific API exceptions to an unchecked infrastructure exception hierarchy. Spring
introduces a DAO exception hierarchy, applicable to any data access strategy. For direct
JDBC, the JdbcTemplate
class mentioned in a previous section
provides connection handling and proper conversion of SQLException
to the
DataAccessException
hierarchy, including translation of database-specific SQL error
codes to meaningful exception classes. For ORM technologies, see the
next section for how to get the same exception
translation benefits.
JdbcTemplate
类与 Springtransaction 支持相结合,并且通过各个Spring 事务管理器支持 JTA 和 JDBC 事务。对于所支持的 ORM 技术,Spring 提供了 Hibernate 和 JPA 支持以及 JTA 支持,方法是通过 Hibernate 和 JPA 事务管理器。有关事务支持的详细信息,请参阅 Transaction Management 章节。
When it comes to transaction management, the JdbcTemplate
class hooks in to the Spring
transaction support and supports both JTA and JDBC transactions, through respective
Spring transaction managers. For the supported ORM technologies, Spring offers Hibernate
and JPA support through the Hibernate and JPA transaction managers as well as JTA support.
For details on transaction support, see the Transaction Management chapter.
Exception Translation
当你已经在 DAO 中使用 Hibernate 或 JPA 时,你必须决定如何处理持久化技术的原生异常类。DAO 根据技术抛出一个 HibernateException
或 PersistenceException
的子类。这些异常都是运行时异常,并且不必声明或捕获。你可能还必须处理 IllegalArgumentException
和 IllegalStateException
。这意味着调用者只能将异常视为通常是致命的,除非他们想要依赖持久化技术的异常结构本身。在不将调用者与实现策略捆绑在一起的情况下,是不可能捕获具体原因(例如,乐观锁失败)的。对于强烈基于 ORM 或不需要任何特殊异常处理(或两者兼而有之)的应用程序,这种权衡可能是可以接受的。然而,Spring 可以通过 @Repository
注释透明地应用异常转换。以下示例(一个适用于 Java 配置,一个适用于 XML 配置)展示了如何执行此操作:
When you use Hibernate or JPA in a DAO, you must decide how to handle the persistence
technology’s native exception classes. The DAO throws a subclass of a HibernateException
or PersistenceException
, depending on the technology. These exceptions are all runtime
exceptions and do not have to be declared or caught. You may also have to deal with
IllegalArgumentException
and IllegalStateException
. This means that callers can only
treat exceptions as being generally fatal, unless they want to depend on the persistence
technology’s own exception structure. Catching specific causes (such as an optimistic
locking failure) is not possible without tying the caller to the implementation strategy.
This trade-off might be acceptable to applications that are strongly ORM-based or
do not need any special exception treatment (or both). However, Spring lets exception
translation be applied transparently through the @Repository
annotation. The following
examples (one for Java configuration and one for XML configuration) show how to do so:
-
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,以便发现的转换器可以拦截抛出的异常并在其上应用适当的转换。
The postprocessor automatically looks for all exception translators (implementations of
the PersistenceExceptionTranslator
interface) and advises all beans marked with the
@Repository
annotation so that the discovered translators can intercept and apply the
appropriate translation on the thrown exceptions.
总结来说,你可以使用纯持久技术 API 和注释来实现 DAO,同时还可以利用 Spring 管理的事务、依赖注入和透明异常转换(如果需要),转换为 Spring 的自定义异常层次结构。
In summary, you can implement DAOs based on the plain persistence technology’s API and annotations while still benefiting from Spring-managed transactions, dependency injection, and transparent exception conversion (if desired) to Spring’s custom exception hierarchies.