From fe5b5022f0de144d05da65b63015229241cf58b2 Mon Sep 17 00:00:00 2001 From: Thomas Risberg Date: Thu, 6 Aug 2009 16:27:20 +0000 Subject: [PATCH] Beverly's edits reviewed; spell checked --- spring-framework-reference/src/orm.xml | 1479 +++++++++++++----------- 1 file changed, 783 insertions(+), 696 deletions(-) diff --git a/spring-framework-reference/src/orm.xml b/spring-framework-reference/src/orm.xml index 6259a519273..1af6ae3ae18 100644 --- a/spring-framework-reference/src/orm.xml +++ b/spring-framework-reference/src/orm.xml @@ -2,193 +2,195 @@ - Object Relational Mapping (ORM) data access + Object Relational Mapping (ORM) Data Access
- Introduction + Introduction to ORM with Spring - The Spring Framework provides integration with Hibernate, - JPA, JDO and iBATIS SQL Maps: in terms of - resource management, DAO implementation support, and transaction - strategies. For example for Hibernate, there is first-class support with - lots of IoC convenience features, addressing many typical Hibernate - integration issues. All of these support packages for O/R (Object - Relational) mappers can be configured through Dependency Injection, can - participate in Spring's resource and transaction management and they - comply with Spring's generic transaction and DAO exception hierarchies. - The curently recommended integration style is to code DAOs against plain - Hibernate/JPA/JDO/etc APIs. The older style of using Spring's DAO - 'templates' is no longer recommended and the coverage of this style can be - found in the Appendix. + The Spring Framework supports integration + with Hibernate, Java Persistence API (JPA), Java Data Objects (JDO) and + iBATIS SQL Maps for resource management, data access object (DAO) + implementation, and transaction strategies. For example for Hibernate, + there is first-class support with lots of IoC convenience features, + addressing many typical Hibernate integration issues. You can configure + all of these supported features for O/R (object relational) mappers through + Dependency Injection. They can participate in Spring's resource + and transaction management,and they comply with Spring's generic + transaction and DAO exception hierarchies. The recommended integration + style is to code DAOs against plain Hibernate, JPA, and JDO APIs. The + older style of using Spring's DAO templates is no longer recommended; + however, coverage of this style can be found in the Appendix. - Spring adds significant support when using the O/R mapping layer of - your choice to create data access applications. First of all, you should - know that once you started using Spring's support for O/R mapping, you - don't have to go all the way. No matter to what extent, you're invited to - review and leverage the Spring approach, before deciding to take the - effort and risk of building a similar infrastructure in-house. Much of the - O/R mapping support, no matter what technology you're using may be used in - a library style, as everything is designed as a set of reusable JavaBeans. - Usage inside a Spring IoC container does provide additional benefits in - terms of ease of configuration and deployment; as such, most examples in - this section show configuration inside a Spring container. + Spring adds significant enhancements to the ORM layer of your choice + when you create data access applications. You can leverage as much of the + integration support as you wish and you should compare this integration + effort with the cost and risk of building a similar infrastructure + in-house. You can use much of the ORM support as you would a library, + regardless of technology, because everything is designed as a set of + reusable JavaBeans. ORM in a Spring IoC container does facilitate + configuration and deployment; thus most examples in this section show + configuration inside a Spring container. - Some of the benefits of using the Spring Framework to create your - ORM DAOs include: + Benefits of using the Spring Framework to create your ORM DAOs + include: - Ease of testing. Spring's IoC approach - makes it easy to swap the implementations and config locations of + Easier testing. Spring's IoC approach makes + it easy to swap the implementations and configuration locations of Hibernate SessionFactory instances, JDBC DataSource instances, transaction - managers, and mappes object implementations (if needed). This makes it - much easier to isolate and test each piece of persistence-related code - in isolation. + managers, and mapped object implementations (if needed). This in turn makes it + much easier to test each piece of persistence-related code in + isolation. Common data access exceptions. Spring can - wrap exceptions from your O/R mapping tool of choice, converting them - from proprietary (potentially checked) exceptions to a common runtime - DataAccessException hierarchy. This allows you to handle most + wrap exceptions from your ORM tool, converting them from proprietary + (potentially checked) exceptions to a common runtime + DataAccessException hierarchy. This feature allows you to handle most persistence exceptions, which are non-recoverable, only in the - appropriate layers, without annoying boilerplate catches/throws, and - exception declarations. You can still trap and handle exceptions - anywhere you need to. Remember that JDBC exceptions (including DB - specific dialects) are also converted to the same hierarchy, meaning - that you can perform some operations with JDBC within a consistent - programming model. + appropriate layers, without annoying boilerplate catches, throws, and + exception declarations. You can still trap and handle exceptions as + necessary. Remember that JDBC exceptions (including DB-specific + dialects) are also converted to the same hierarchy, meaning that you + can perform some operations with JDBC within a consistent programming + model. General resource management. Spring application contexts can handle the location and configuration of - Hibernate SessionFactory instances, - JDBC DataSource instances, iBATIS SQL - Maps configuration objects, and other related resources. This makes - these values easy to manage and change. Spring offers efficient, easy - and safe handling of persistence resources. For example: related code - using Hibernate generally needs to use the same Hibernate - Session for efficiency and proper - transaction handling. Spring makes it easy to transparently create and - bind a Session to the current thread, - either by using an explicit 'template' wrapper class at the Java code - level or by exposing a current Session - through the Hibernate SessionFactory - (for DAOs based on plain Hibernate API). Thus Spring solves many of - the issues that repeatedly arise from typical Hibernate usage, for any - transaction environment (local or JTA). + Hibernate SessionFactory instances, JPA + EntityManagerFactory instances, JDBC + DataSource instances, iBATIS SQL Maps + configuration objects, and other related resources. This makes these + values easy to manage and change. Spring offers efficient, easy, and + safe handling of persistence resources. For example, related code that + uses Hibernate generally needs to use the same Hibernate + Session to ensure efficiency and proper + transaction handling. Spring makes it easy to create and bind a + Session to the current thread + transparently, by + exposing a current Session through the + Hibernate SessionFactory. Thus Spring + solves many chronic problems of typical Hibernate usage, for any local + or JTA transaction environment. - Integrated transaction management. Spring - allows you to wrap your O/R mapping code with either a declarative, - AOP style method interceptor, or an explicit 'template' wrapper class - at the Java code level. In either case, transaction semantics are - handled for you, and proper transaction handling (rollback, etc) in - case of exceptions is taken care of. As discussed below, you also get - the benefit of being able to use and swap various transaction - managers, without your Hibernate/JDO related code being affected: for - example, between local transactions and JTA, with the same full - services (such as declarative transactions) available in both - scenarios. As an additional benefit, JDBC-related code can fully - integrate transactionally with the code you use to do O/R mapping. - This is useful for data access that's not suitable for O/R mapping, - such as batch processing or streaming of BLOBs, which still needs to + Integrated transaction management. You can + wrap your ORM code with a declarative, aspect-oriented programming + (AOP) style method interceptor either through the + @Transactional annotation or by + explicitly configuring the transaction AOP advice in an XML + configuration file. In both cases, transaction semantics and exception + handling (rollback, and so on) are handled for you. As discussed + below, in Resource and transaction + management, you can also swap various transaction managers, + without affecting your ORM-related code. For example, you can swap + between local transactions and JTA, with the same full services (such + as declarative transactions) available in both scenarios. + Additionally, JDBC-related code can fully integrate transactionally + with the code you use to do ORM. This is useful for data access that + is not suitable for ORM, such as batch processing and BLOB streaming, + which still need to share common transactions with ORM operations. - The PetClinic sample in the Spring distribution offers alternative - DAO implementations and application context configurations for JDBC, - Hibernate, and JPA. PetClinic can therefore serve as working sample app - that illustrates the use of Hibernate and JPA in a Spring web application. - It also leverages declarative transaction demarcation with different - transaction strategies. + TODO: + provide links to current samples
General ORM integration considerations - This section highlights some common considerations regardles of - which ORM technology you use. The Hibernate section provides more details - and also show these features/configurations in a concrete context. + This section highlights considerations that apply to all ORM + technologies. The section provides more + details and also show these features and configurations in a concrete + context. - The major goal of Spring's ORM integration is to allow for 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. 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 don't need to 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. + 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. 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 + Resource and transaction management - Typical business applications are often cluttered with repetitive + Typical business applications are cluttered with repetitive resource management code. Many projects try to invent their own - solutions for this issue, sometimes sacrificing proper handling of - failures for programming convenience. Spring advocates strikingly simple - solutions for proper resource handling, namely IoC via templating in the - case of JDBC and applying AOP interceptors for the ORM - technologies. + 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. - The infrastructure cares for proper resource handling, and for + 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 cares for connection handling, and for proper conversion of - SQLException to the + 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. - When it comes to transaction management the + When it comes to transaction management, the JdbcTemplate class hooks in to the Spring - transaction support and supports both JTA and JDBC transactions, via + transaction support and supports both JTA and JDBC transactions, through respective Spring transaction managers. For the supported ORM - technologies Spring offers Hibernate, JPA and JDO support via the - Hibernate / JPA / JDO transaction managers as well as JTA support. For - more details on the transaction support see the chapter. + technologies Spring offers Hibernate, JPA and JDO support through the + Hibernate, JPA, and JDO transaction managers as well as JTA support. For + details on transaction support, see the + chapter.
- Exception Translation + Exception translation - Using Hibernate, JDO or JPA in a DAO means that you will have to - decide how to handle the persistence technology's native exception - classes. The DAO could potentially throw a subclass of a - HibernateException, - JDOException or - PersistenceException depending on the technology - in use. These exceptions are all run-time exceptions and does not have - to be declared or caught. You would potentially also have to deal with + When you use Hibernate, JPA, or JDO in a DAO, you must decide how + to handle the persistence technology's native exception classes. The DAO + throws a subclass of a HibernateException, + PersistenceException or + JDOException depending on the technology. + These exceptions are all run-time 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 generally fatal - unless they want to - depend on the persistence technology's own exception structure. Catching + can only treat exceptions as 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 tradeoff + without tying the caller to the implementation strategy. This trade off might be acceptable to applications that are strongly ORM-based and/or - do not need any special exception treatment. However, Spring offers a - solution allowing exception translation to be applied transparently - through the @Repository - annotation: + do not need any special exception treatment. However, Spring enables + exception translation to be applied transparently through the + @Repository annotation: @Repository public class ProductDaoImpl implements ProductDao { @@ -206,16 +208,16 @@ public class ProductDaoImpl implements ProductDao { </beans> - The postprocessor will automatically look for all exception + The postprocessor automatically looks for all exception translators (implementations of the PersistenceExceptionTranslator interface) - and advise all beans marked with the + 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. - In summary: DAOs can be implemented based on the plain persistence - technology's API and annotations, while still being able to benefit from + 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. @@ -235,24 +237,27 @@ public class ProductDaoImpl implements ProductDao { will then cover the other ORM technologies, showing briefer examples there. - Note: As of Spring 2.5, Spring requires Hibernate 3.1 or - higher. Neither Hibernate 2.1 nor Hibernate 3.0 are supported - anymore. + + As of Spring 2.5, Spring requires Hibernate 3.1 or later. + Neither Hibernate 2.1 nor Hibernate 3.0 are supported. +
<interfacename>SessionFactory</interfacename> setup in a Spring container To avoid tying application objects to hard-coded resource lookups, - Spring allows you to define resources such as a JDBC + you can define resources such as a JDBC DataSource or a Hibernate SessionFactory as beans in the Spring - container. Application objects that need to access resources just - receive references to such pre-defined instances via bean references - (the DAO definition in the next section illustrates this). The following - excerpt from an XML application context definition shows how to set up a - JDBC DataSource and a Hibernate - SessionFactory on top of it: + container. Application objects that need to access resources receive + references to such predefined instances through bean references, as + illustrated in the DAO definition in the next section. + + The following excerpt from an XML application context definition + shows how to set up a JDBC DataSource and a + Hibernate SessionFactory on top of + it: <beans> @@ -279,7 +284,7 @@ public class ProductDaoImpl implements ProductDao { </beans> - Note that switching from a local Jakarta Commons DBCP + Switching from a local Jakarta Commons DBCP BasicDataSource to a JNDI-located DataSource (usually managed by an application server) is just a matter of configuration: @@ -300,13 +305,13 @@ public class ProductDaoImpl implements ProductDao {
Implementing DAOs based on plain Hibernate 3 API - Hibernate 3 provides a feature called "contextual Sessions", where + Hibernate 3 has a feature called contextual sessions, wherein Hibernate itself manages one current Session per transaction. This is roughly equivalent to Spring's synchronization of one Hibernate Session per transaction. A corresponding - DAO implementation looks like as follows, based on the plain Hibernate - API: + DAO implementation resembles the following example, based on the plain + Hibernate API: public class ProductDaoImpl implements ProductDao { @@ -324,8 +329,8 @@ public class ProductDaoImpl implements ProductDao { } } - This style is very similar to what you will find in the Hibernate - reference documentation and examples, except for holding the + This style is similar to that of the Hibernate reference + documentation and examples, except for holding the SessionFactory in an instance variable. We strongly recommend such an instance-based setup over the old-school static HibernateUtil class @@ -333,13 +338,13 @@ public class ProductDaoImpl implements ProductDao { keep any resources in static variables unless absolutely necessary.) - The above DAO follows the Dependency Injection pattern: it fits - nicely into a Spring IoC container, just like it would if coded against + The above DAO follows the dependency injection pattern: it fits + nicely into a Spring IoC container, just as it would if coded against Spring's HibernateTemplate. Of course, such a DAO - can also be set up in plain Java (for example, in unit tests): simply + can also be set up in plain Java (for example, in unit tests). Simply instantiate it and call setSessionFactory(..) - with the desired factory reference. As a Spring bean definition, it - would look as follows: + with the desired factory reference. As a Spring bean definition, the DAO + would resemble the following: <beans> @@ -359,8 +364,8 @@ public class ProductDaoImpl implements ProductDao { not have to be declared or caught), which means that callers can only treat exceptions as generally fatal - unless they want to depend on Hibernate's own exception hierarchy. Catching specific causes such as an - optimistic locking failure is not possible without tieing the caller to - the implementation strategy. This tradeoff might be acceptable to + 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 Hibernate-based and/or do not need any special exception treatment. @@ -370,13 +375,13 @@ public class ProductDaoImpl implements ProductDao { any Spring transaction strategy, returning the current Spring-managed transactional Session even with HibernateTransactionManager. Of course, the - standard behavior of that method remains: returning the current + standard behavior of that method remains the return of the current Session associated with the ongoing JTA - transaction, if any (no matter whether driven by Spring's - JtaTransactionManager, by EJB CMT, or by - JTA). + transaction, if any. This behavior applies regardless of whether you are + using Spring's JtaTransactionManager, EJB + container managed transactions (CMTs), or JTA. - In summary: DAOs can be implemented based on the plain Hibernate 3 + In summary: you can implement DAOs based on the plain Hibernate 3 API, while still being able to participate in Spring-managed transactions.
@@ -384,23 +389,28 @@ public class ProductDaoImpl implements ProductDao {
Declarative transaction demarcation - We recommended that you use Spring's declarative transaction + We recommend that you use Spring's declarative transaction support, which enables you to replace explicit transaction demarcation - API calls in your Java code with an AOP transaction interceptor - configured in a Spring container using Java annotations or XML. This - allows you to keep business services free of repetitive transaction - demarcation code, and allows you to focus on adding business logic which - is where the real value of your application lies. + API calls in your Java code with an AOP transaction interceptor. This + transaction interceptor can be configured in a Spring container using + either Java annotations or XML.This declarative transaction capability allows you + to keep business services free of repetitive transaction demarcation + code and to focus on adding business logic, which is the real value of + your application. - You are strongly encouraged to read the - section entitled if you - have not done so already prior to continuing. + Prior to continuing, you are strongly + encouraged to read if you + have not done so. Furthermore, transaction semantics like propagation behavior and isolation level can be changed in a configuration file and do not affect - the business service implementations. + the business service implementations. + + The following example shows how you can configure an AOP + transaction interceptor, using XML, for a simple service class: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -440,6 +450,8 @@ public class ProductDaoImpl implements ProductDao { </beans> + This is the service class that is advised: + public class ProductServiceImpl implements ProductService { private ProductDao productDao; @@ -456,10 +468,11 @@ public class ProductDaoImpl implements ProductDao { } } - For completenes we will also show an attribute-support based - configuration. We annotate the service layer with @Transactional - annotations and instruct the Spring container to find these annotations - and provide transactional semantics for these annotated methods. + We also show an attribute-support based configuration, in the + following example. You + annotate the service layer with @Transactional annotations and instruct + the Spring container to find these annotations and provide transactional + semantics for these annotated methods. public class ProductServiceImpl implements ProductService { @@ -483,9 +496,11 @@ public class ProductDaoImpl implements ProductDao { } As you can see from the following configuration example, the - configuration is much simplified while still providing the same - functionality driven by the annotations in the service layer - code. + configuration is much simplified, compared to the XML example above, + while still providing the same functionality driven by the annotations + in the service layer code. All you need to provide is the + TransactionManager implementation and a "<tx:annotation-driven/>" + entry. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -518,18 +533,18 @@ public class ProductDaoImpl implements ProductDao {
Programmatic transaction demarcation - Transactions can be demarcated in a higher level of the + You can demarcate transactions in a higher level of the application, on top of such lower-level data access services spanning - any number of operations. There are no restrictions on the - implementation of the surrounding business service here as well, it just - needs a Spring PlatformTransactionManager. Again, - the latter can come from anywhere, but preferably as bean reference via - a setTransactionManager(..) method - just like - the productDAO should be set via a + any number of operations. Nor do restrictions exist on the + implementation of the surrounding business service; it just needs a + Spring PlatformTransactionManager. Again, the + latter can come from anywhere, but preferably as a bean reference + through a setTransactionManager(..) method, + just as the productDAO should be set by a setProductDao(..) method. The following snippets show a transaction manager and a business service definition in a Spring application context, and an example for a business method - implementation. + implementation: <beans> @@ -573,9 +588,9 @@ public class ProductDaoImpl implements ProductDao { checked application exception to be thrown with the callback code, while TransactionTemplate is restricted to unchecked exceptions within the callback. - TransactionTemplate will trigger a rollback in - case of an unchecked application exception, or if the transaction has - been marked rollback-only by the application (via + TransactionTemplate triggers a rollback in case + of an unchecked application exception, or if the transaction is marked + rollback-only by the application (via TransactionStatus). TransactionInterceptor behaves the same way by default but allows configurable rollback policies per method. @@ -593,26 +608,25 @@ public class ProductDaoImpl implements ProductDao { ThreadLocal Session under the hood) or a JtaTransactionManager (delegating to the JTA - subsystem of the container) for Hibernate applications. You could even - use a custom PlatformTransactionManager - implementation. So switching from native Hibernate transaction - management to JTA, such as when facing distributed transaction - requirements for certain deployments of your application, is just a - matter of configuration. Simply replace the Hibernate transaction - manager with Spring's JTA transaction implementation. Both transaction - demarcation and data access code will work without changes, as they just - use the generic transaction management APIs. + subsystem of the container) for Hibernate applications. You can even use + a custom PlatformTransactionManager + implementation. Switching from native Hibernate transaction management + to JTA, such as when facing distributed transaction requirements for + certain deployments of your application, is just a matter of + configuration. Simply replace the Hibernate transaction manager with + Spring's JTA transaction implementation. Both transaction demarcation + and data access code will work without changes, because they just use + the generic transaction management APIs. For distributed transactions across multiple Hibernate session factories, simply combine JtaTransactionManager as a transaction strategy with multiple - LocalSessionFactoryBean definitions. Each of your - DAOs then gets one specific - SessionFactory reference passed into its - corresponding bean property. If all underlying JDBC data sources are - transactional container ones, a business service can demarcate - transactions across any number of DAOs and any number of session - factories without special regard, as long as it is using + LocalSessionFactoryBean definitions. Each DAO + then gets one specific SessionFactory + reference passed into its corresponding bean property. If all underlying + JDBC data sources are transactional container ones, a business service + can demarcate transactions across any number of DAOs and any number of + session factories without special regard, as long as it is using JtaTransactionManager as the strategy. <beans> @@ -682,164 +696,175 @@ public class ProductDaoImpl implements ProductDao { Both HibernateTransactionManager and JtaTransactionManager allow for proper JVM-level - cache handling with Hibernate - without container-specific transaction - manager lookup or JCA connector (as long as not using EJB to initiate - transactions). + cache handling with Hibernate, without container-specific transaction + manager lookup or a JCA connector (if you are not using EJB to initiate + transactions). HibernateTransactionManager can export the - JDBC Connection used by Hibernate to - plain JDBC access code, for a specific - DataSource. This allows for high-level - transaction demarcation with mixed Hibernate/JDBC data access completely - without JTA, as long as you are just accessing one database! - HibernateTransactionManager will automatically - expose the Hibernate transaction as JDBC transaction if the passed-in - SessionFactory has been set up with a - DataSource (through the "dataSource" - property of the LocalSessionFactoryBean class). - Alternatively, the DataSource that the - transactions are supposed to be exposed for can also be specified - explicitly, through the "dataSource" property of the + Hibernate JDBC Connection to plain JDBC + access code, for a specific DataSource. + This capability allows for high-level transaction demarcation with mixed + Hibernate and JDBC data access completely without JTA, if you are + accessing only one database. + HibernateTransactionManager automatically exposes + the Hibernate transaction as a JDBC transaction if you have set up the + passed-in SessionFactory with a + DataSource through the + dataSource property of the + LocalSessionFactoryBean class. Alternatively, you + can specify explicitly the DataSource for + which the transactions are supposed to be exposed through the + dataSource property of the HibernateTransactionManager class.
- Container resources versus local resources + Comparing container-managed and locally defined resources<!--I've revised to better communicate the point of the section, which I think has to do with --><!--comparing spring's local support for transactions as opposed to container support. Revise as necessary. +TR: REVISED, PLS REVIEW. Changed to heading *resources* since it technically could be more than transactions i.e. caching--> - Spring's resource management allows for simple switching between a - JNDI SessionFactory and a local one, - without having to change a single line of application code. The decision - as to whether to keep the resource definitions in the container or - locally within the application, is mainly a matter of the transaction - strategy being used. Compared to a Spring-defined local + You can switch between a container-managed JNDI + SessionFactory and a + locally defined one, without having to change a single line of + application code. Whether to keep resource definitions in the container + or locally within the application is mainly a matter of the transaction + strategy that you use. Compared to a Spring-defined local SessionFactory, a manually registered JNDI SessionFactory does not provide any benefits. Deploying a SessionFactory through Hibernate's JCA connector provides the added value of - participating in the J2EE server's management infrastructure, but does - not add actual value beyond that. + participating in the Java EE server's management infrastructure, but + does not add actual value beyond that. - An important benefit of Spring's transaction support is that it - isn't bound to a container at all. Configured to any other strategy than - JTA, it will work in a standalone or test environment too. Especially - for the typical case of single-database transactions, this is a very - lightweight and powerful alternative to JTA. When using local EJB - Stateless Session Beans to drive transactions, you depend both on an EJB - container and JTA - even if you just access a single database anyway, - and just use SLSBs for declarative transactions via CMT. The alternative - of using JTA programmatically requires a J2EE environment as well. JTA - does not just involve container dependencies in terms of JTA itself and - of JNDI DataSource instances. For - non-Spring JTA-driven Hibernate transactions, you have to use the + Spring's transaction support is not bound to a container. + Configured with any strategy other than JTA, transaction support also + works in a stand-alone or test environment. Especially in the typical + case of single-database transactions, Spring's single-resource local + transaction support is + a lightweight and powerful alternative to JTA. When you use local EJB + stateless session beans to drive transactions, you depend both on an EJB + container and JTA, even if you access only a single database, and only + use stateless session beans to provide declarative transactions through + container-managed transactions. Also, + direct use of JTA programmatically requires a Java EE environment as + well. JTA does not involve only container dependencies in terms of JTA + itself and of JNDI DataSource instances. + For non-Spring, JTA-driven Hibernate transactions, you have to use the Hibernate JCA connector, or extra Hibernate transaction code with the - TransactionManagerLookup being configured - for proper JVM-level caching. + TransactionManagerLookup configured for + proper JVM-level caching. - Spring-driven transactions can work with a locally defined - Hibernate SessionFactory nicely, just - like with a local JDBC DataSource - if - accessing a single database, of course. Therefore you just have to fall - back to Spring's JTA transaction strategy when actually facing - distributed transaction requirements. Note that a JCA connector needs - container-specific deployment steps, and obviously JCA support in the - first place. This is far more hassle than deploying a simple web app - with local resource definitions and Spring-driven transactions. And you - often need the Enterprise Edition of your container, as for example - WebLogic Express does not provide JCA. A Spring application with local - resources and transactions spanning one single database will work in any - J2EE web container (without JTA, JCA, or EJB) - like Tomcat, Resin, or - even plain Jetty. Additionally, such a middle tier can be reused in - desktop applications or test suites easily. + Spring-driven transactions can work as well with a locally defined + Hibernate SessionFactory as they do with + a local JDBC DataSource if they are + accessing a single database. Thus you only have to use Spring's JTA + transaction strategy when you have distributed transaction requirements. + A JCA connector requires container-specific deployment steps, and + obviously JCA support in the first place. This configuration requires + more work than deploying a simple web application with local resource + definitions and Spring-driven transactions. Also, you often need the + Enterprise Edition of your container if you are using, for example, + WebLogic Express, which does not provide JCA. A Spring application with + local resources and transactions spanning one single database works in + any Java EE web container (without JTA, JCA, or EJB) such as Tomcat, + Resin, or even plain Jetty. Additionally, you can easily reuse such a + middle tier in desktop applications or test suites. - All things considered: if you do not use EJB, stick with local + All things considered, if you do not use EJBs, stick with local SessionFactory setup and Spring's HibernateTransactionManager or - JtaTransactionManager. You will get all of the - benefits including proper transactional JVM-level caching and - distributed transactions, without any container deployment hassle. JNDI - registration of a Hibernate - SessionFactory via the JCA connector - really only adds value when used in conjunction with EJBs. + JtaTransactionManager. You get all of the + benefits, including proper transactional JVM-level caching and + distributed transactions, without the inconvenience of container + deployment. JNDI registration of a Hibernate + SessionFactory through the JCA connector + only adds value when used in conjunction with EJBs.
- Spurious application server warnings when using Hibernate + Spurious application server warnings with Hibernate In some JTA environments with very strict XADataSource implementations -- currently - only some WebLogic and WebSphere versions -- when using Hibernate - configured without any awareness of the JTA + only some WebLogic Server and WebSphere versions -- when Hibernate is + configured without regard to the JTA PlatformTransactionManager object for that environment, it is possible for spurious warning or exceptions to - show up in the application server log. These warnings or exceptions will - say something to the effect that the connection being accessed is no - longer valid, or JDBC access is no longer valid, possibly because the - transaction is no longer active. As an example, here is an actual - exception from WebLogic: + show up in the application server log. These warnings or exceptions + indicate that the connection being accessed is no longer valid, or JDBC + access is no longer valid, possibly because the transaction is no longer + active. As an example, here is an actual exception from WebLogic: java.sql.SQLException: The transaction is no longer active - status: 'Committed'. No further JDBC access is allowed within this transaction. - This warning is easy to resolve by simply making Hibernate aware - of the JTA PlatformTransactionManager - instance, to which it will also synchronize (along with Spring). This - may be done in two ways: + You resolve this warning by simply making Hibernate aware of the + JTA PlatformTransactionManager instance, + to which it will synchronize (along with Spring). You have two options + for doing this: If in your application context you are already directly obtaining the JTA PlatformTransactionManager object - (presumably from JNDI via + (presumably from JNDI through JndiObjectFactoryBean/<jee:jndi-lookup>) - and feeding it for example to Spring's + and feeding it, for example, to Spring's JtaTransactionManager, then the easiest way - is to simply specify a reference to this as the value of - LocalSessionFactoryBean's - jtaTransactionManager property. Spring will - then make the object available to Hibernate. + is to specify a reference to the bean defining this JTA + PlatformTransactionManager + instance as + the value of the jtaTransactionManager property + for LocalSessionFactoryBea. Spring then makes + the object available to Hibernate. More likely you do not already have the JTA - PlatformTransactionManager instance - (since Spring's JtaTransactionManager can - find it itself) so you need to instead configure Hibernate to also - look it up directly. This is done by configuring an AppServer - specific TransactionManagerLookup class in the - Hibernate configuration, as described in the Hibernate - manual. + PlatformTransactionManager instance, + because Spring's JtaTransactionManager can + find it itself. Thus + you need to configure Hibernate to look up JTA + PlatformTransactionManager directly. + You do this by configuring an application server- specific + TransactionManagerLookup class in the Hibernate + configuration, as described in the Hibernate manual. - It is not necessary to read any more for proper usage, but the - full sequence of events with and without Hibernate being aware of the - JTA PlatformTransactionManager will now - be described. + The remainder of this section describes the sequence of events + that occur with and without Hibernate's awareness of the JTA + PlatformTransactionManager. When Hibernate is not configured with any awareness of the JTA - PlatformTransactionManager, the sequence - of events when a JTA transaction commits is as follows: + PlatformTransactionManager, the following + events occur when a JTA transaction commits: - + - JTA transaction commits + The JTA transaction commits. Spring's JtaTransactionManager is - synchronized to the JTA transaction, so it is called back via an + synchronized to the JTA transaction, so it is called back through an afterCompletion callback by the JTA transaction manager. - Among other activities, this can trigger a callback by Spring - to Hibernate, via Hibernate's - afterTransactionCompletion callback (used to - clear the Hibernate cache), followed by an explicit + Among other activities, this synchronizationcan + trigger a callback by Spring to Hibernate, through Hibernate's + afterTransactionCompletion callback (used + to clear the Hibernate cache), followed by an explicit close() call on the Hibernate Session, which - results in Hibernate trying to close() the JDBC + causes Hibernate to attempt to close() the JDBC Connection. @@ -847,25 +872,25 @@ public class ProductDaoImpl implements ProductDao { In some environments, this Connection.close() call then triggers the warning or error, as the application server no longer considers the - Connection usable at all, since the + Connection usable at all, because the transaction has already been committed. - + When Hibernate is configured with awareness of the JTA - PlatformTransactionManager, the sequence - of events when a JTA transaction commits is instead as follows: + PlatformTransactionManager, the following + events occur when a JTA transaction commits: - + - JTA transaction is ready to commit + the JTA transaction is ready to commit. Spring's JtaTransactionManager is - synchronized to the JTA transaction, so it is called back via a - beforeCompletion callback by the JTA - transaction manager. + synchronized to the JTA transaction, so the transaction is called + back through a beforeCompletion callback by the + JTA transaction manager. @@ -877,23 +902,23 @@ public class ProductDaoImpl implements ProductDao { - JTA Transaction commits + The JTA transaction commits. - Hibernate is synchronized to the JTA transaction, so it is - called back via an afterCompletion callback by - the JTA transaction manager, and can properly clear its - cache. + Hibernate is synchronized to the JTA transaction, so the + transaction is called back through an + afterCompletion callback by the JTA transaction + manager, and can properly clear its cache. - +
JDO - Spring supports the standard JDO 2.0/2.1 API as data access + Spring supports the standard JDO 2.0 and 2.1 APIs as data access strategy, following the same style as the Hibernate support. The corresponding integration classes reside in the org.springframework.orm.jdo package. @@ -904,7 +929,7 @@ public class ProductDaoImpl implements ProductDao { Spring provides a LocalPersistenceManagerFactoryBean class that - allows for defining a local JDO + allows you to define a local JDO PersistenceManagerFactory within a Spring application context: @@ -916,19 +941,22 @@ public class ProductDaoImpl implements ProductDao { </beans> - Alternatively, a - PersistenceManagerFactory can also be set - up through direct instantiation of a + Alternatively, you can set up a + PersistenceManagerFactory through direct + instantiation of a PersistenceManagerFactory implementation class. A JDO PersistenceManagerFactory implementation class follows the JavaBeans pattern, just like a JDBC DataSource implementation class, which is - a natural fit for configuration using Spring. This setup style usually - supports a Spring-defined JDBC + a natural fit for a configuration that uses Spring. This setup style + usually supports a Spring-defined JDBC DataSource, passed into the - "connectionFactory" property. For example, for the open source JDO - implementation DataNucleus (formerly JPOX) (http://www.datanucleus.org/): + connectionFactory property. For example, for the + open source JDO implementation DataNucleus (formerly JPOX) (http://www.datanucleus.org/), + this is the XML configuration of the + PersistenceManagerFactory + implementation: <beans> @@ -946,27 +974,28 @@ public class ProductDaoImpl implements ProductDao { </beans> - A JDO PersistenceManagerFactory can - also be set up in the JNDI environment of a J2EE application server, - usually through the JCA connector provided by the particular JDO - implementation. Spring's standard JndiObjectFactoryBean / + You can also set up JDO + PersistenceManagerFactory in the JNDI + environment of a Java EE application server, usually through the JCA + connector provided by the particular JDO implementation. Spring's + standard JndiObjectFactoryBean / <jee:jndi-lookup> can be used to retrieve and expose such a PersistenceManagerFactory. However, - outside an EJB context, there is often no compelling benefit in holding - the PersistenceManagerFactory in JNDI: - only choose such setup for a good reason. See "container resources - versus local resources" in the Hibernate section for a discussion; the - arguments there apply to JDO as well. + outside an EJB context, no real benefit exists in holding the + PersistenceManagerFactory in JNDI: only + choose such a setup for a good reason. See for a discussion; the arguments + there apply to JDO as well.
Implementing DAOs based on the plain JDO API - DAOs can also be written against plain JDO API, without any Spring - dependencies, directly using an injected - PersistenceManagerFactory. A - corresponding DAO implementation looks like as follows: + DAOs can also be written directly against plain JDO API, without + any Spring dependencies, by using an injected + PersistenceManagerFactory. The following + is an example of a corresponding DAO implementation: public class ProductDaoImpl implements ProductDao { @@ -989,9 +1018,9 @@ public class ProductDaoImpl implements ProductDao { } } - As the above DAO still follows the Dependency Injection pattern, - it still fits nicely into a Spring container, just like it would if - coded against Spring's JdoTemplate: + Because the above DAO follows the dependency injection pattern, it + fits nicely into a Spring container, just as it would if coded against + Spring's JdoTemplate: <beans> @@ -1001,14 +1030,14 @@ public class ProductDaoImpl implements ProductDao { </beans> - The main issue with such DAOs is that they always get a new + The main problem with such DAOs is that they always get a new PersistenceManager from the factory. To - still access a Spring-managed transactional - PersistenceManager, consider defining a + access a Spring-managed transactional + PersistenceManager, define a TransactionAwarePersistenceManagerFactoryProxy (as included in Spring) in front of your target - PersistenceManagerFactory, passing the - proxy into your DAOs. + PersistenceManagerFactory, then passing a + reference to that proxy into your DAOs as in the following example: <beans> @@ -1023,22 +1052,22 @@ public class ProductDaoImpl implements ProductDao { </beans> - Your data access code will then receive a transactional + Your data access code will receive a transactional PersistenceManager (if any) from the PersistenceManagerFactory.getPersistenceManager() method that it calls. The latter method call goes through the proxy, - which will first check for a current transactional + which first checks for a current transactional PersistenceManager before getting a new - one from the factory. close() calls on the - PersistenceManager will be ignored in - case of a transactional + one from the factory. Any close() calls on the + PersistenceManager are ignored in case of + a transactional PersistenceManager. - If your data access code will always run within an active - transaction (or at least within active transaction synchronization), it - is safe to omit the PersistenceManager.close() - call and thus the entire finally block, which you - might prefer to keep your DAO implementations concise: + If your data access code always runs within an active transaction + (or at least within active transaction synchronization), it is safe to + omit the PersistenceManager.close() call and + thus the entire finally block, which you might do to + keep your DAO implementations concise: public class ProductDaoImpl implements ProductDao { @@ -1057,9 +1086,9 @@ public class ProductDaoImpl implements ProductDao { } With such DAOs that rely on active transactions, it is recommended - to enforce active transactions through turning + that you enforce active transactions through turning off TransactionAwarePersistenceManagerFactoryProxy's - "allowCreate" flag off: + allowCreate flag: <beans> @@ -1083,35 +1112,34 @@ public class ProductDaoImpl implements ProductDao { However, the DAO throws plain JDOException (which is unchecked, so does not have to be declared or caught), which means that callers can only - treat exceptions as generally fatal - unless they want to depend on - JDO'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 tradeoff might be acceptable to + treat exceptions as fatal, unless you want to depend on JDO'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 JDO-based and/or do not need any special exception treatment. - In summary: DAOs can be implemented based on plain JDO API, while - still being able to participate in Spring-managed transactions. This - might in particular appeal to people already familiar with JDO, feeling - more natural to them. However, such DAOs will throw plain - JDOException; conversion to Spring's - DataAccessException would have to happen - explicitly (if desired). + In summary, you can DAOs based on the plain JDO API, and they can + still participate in Spring-managed transactions. This strategy might + appeal to you if you are already familiar with JDO. However, such DAOs + throw plain JDOException, and you would + have to convert explicitly to Spring's + DataAccessException (if desired).
Transaction management + + You are strongly encouraged to read if you have not done so, to get a + more detailed coverage of Spring's declarative transaction + support. + + To execute service operations within transactions, you can use Spring's common declarative transaction facilities. For example: - - You are strongly encouraged to read the - section entitled if you - have not done so to get a more detailed coverage of Spring's - declarative transaction support. - - <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" @@ -1149,17 +1177,16 @@ public class ProductDaoImpl implements ProductDao { </beans> - Note that JDO requires an active transaction when modifying a - persistent object. There is no concept like a non-transactional flush in - JDO, in contrast to Hibernate. For this reason, the chosen JDO - implementation needs to be set up for a specific environment: in - particular, it needs to be explicitly set up for JTA synchronization, to - detect an active JTA transaction itself. This is not necessary for local - transactions as performed by Spring's - JdoTransactionManager, but it is necessary for - participating in JTA transactions (whether driven by Spring's - JtaTransactionManager or by EJB CMT / plain - JTA). + JDO requires an active transaction to modify a persistent object. + The non-transactional flush concept does not exist in JDO, in contrast + to Hibernate. For this reason, you need to set up the chosen JDO + implementation for a specific environment. Specifically, you need to set + it up explicitly for JTA synchronization, to detect an active JTA + transaction itself. This is not necessary for local transactions as + performed by Spring's JdoTransactionManager, but + it is necessary to participate in JTA transactions, whether driven by + Spring's JtaTransactionManager or by EJB CMT and + plain JTA. JdoTransactionManager is capable of exposing a JDO transaction to JDBC access code that accesses the same @@ -1175,45 +1202,46 @@ public class ProductDaoImpl implements ProductDao { As an advanced feature, both JdoTemplate and interfacename support a custom JdoDialect, to be passed into the - "jdoDialect" bean property. In such a scenario, the DAOs won't receive a - PersistenceManagerFactory reference but - rather a full JdoTemplate instance instead (for - example, passed into JdoDaoSupport's - "jdoTemplate" property). A JdoDialect - implementation can enable some advanced features supported by Spring, - usually in a vendor-specific manner: + jdoDialect bean property. In this scenario, the DAOs will + not receive a PersistenceManagerFactory + reference but rather a full JdoTemplate instance + (for example, passed into the jdoTemplate + property of JdoDaoSupport. Using a + JdoDialect implementation, you can enable + advanced features supported by Spring, usually in a vendor-specific + manner: - applying specific transaction semantics (such as custom - isolation level or transaction timeout) + Applying specific transaction semantics such as custom + isolation level or transaction timeout - retrieving the transactional JDBC - Connection (for exposure to - JDBC-based DAOs) + Retrieving the transactional JDBC + Connection for exposure to JDBC-based + DAOs - applying query timeouts (automatically calculated from - Spring-managed transaction timeout) + Applying query timeouts, which are automatically calculated + from Spring-managed transaction timeouts - eagerly flushing a - PersistenceManager (to make - transactional changes visible to JDBC-based data access code) + Eagerly flushing a + PersistenceManager, to make + transactional changes visible to JDBC-based data access code - advanced translation of JDOExceptions to + Advanced translation of JDOExceptions to Spring DataAccessExceptions See the JdoDialect Javadoc for more details - on its operations and how they are used within Spring's JDO + on its operations and how to use them within Spring's JDO support.
@@ -1221,8 +1249,8 @@ public class ProductDaoImpl implements ProductDao {
JPA - Spring JPA (available under the - org.springframework.orm.jpa package) offers + The Spring JPA, available under the + org.springframework.orm.jpa package, offers comprehensive support for the Java Persistence API in a similar manner to the integration with @@ -1230,21 +1258,28 @@ public class ProductDaoImpl implements ProductDao { order to provide additional features.
- JPA setup in a Spring environment + Three options for JPA setup in a Spring environment - Spring JPA offers three ways of setting up JPA - EntityManagerFactory: + The Spring JPA support offers three ways of setting up the JPA + EntityManagerFactory that will be used by + the application to obtain an entity manager.
<classname>LocalEntityManagerFactoryBean</classname> + + Only use this option in simple deployment environments such as + stand-alone applications and integration tests. + + The LocalEntityManagerFactoryBean creates an EntityManagerFactory suitable for - environments which solely use JPA for data access. The factory bean - will use the JPA PersistenceProvider - autodetection mechanism (according to JPA's Java SE bootstrapping) - and, in most cases, requires only the persistence unit name to be - specified: + simple deployment environments where the application uses only JPA for + data access. The factory bean uses the JPA + PersistenceProvider autodetection + mechanism (according to JPA's Java SE bootstrapping) and, in most + cases, requires you to specify only the persistence unit name: <beans> @@ -1254,26 +1289,30 @@ public class ProductDaoImpl implements ProductDao { </beans> - This is the simplest but also most limited form of JPA - deployment. There is no way to link to an existing JDBC - DataSource and no support for global - transactions, for example. Furthermore, weaving (byte-code - transformation) of persistent classes is provider-specific, often - requiring a specific JVM agent to specified on startup. All in all, - this option is only really sufficient for standalone applications and - test environments (which is exactly what the JPA specification - designed it for). - - Only use this option in simple deployment environments - like standalone applications and integration tests. + This form of JPA deployment is the simplest and the most + limited. You cannot refer to + an existing JDBC DataSource bean + definition and no support for global transactions exists. Furthermore, + weaving (byte-code transformation) of persistent classes is + provider-specific, often requiring a specific JVM agent to specified + on startup. This option is sufficient only for stand-alone + applications and test environments, for which the JPA specification is + designed.
- <classname>Obtaining an EntityManagerFactory from - JNDI</classname> + Obtaining an <classname>EntityManagerFactory</classname> from + JNDI + + + Use this option when deploying to a Java EE 5 server. Check + your server's documentation on how to deploy a custom JPA provider + into your server, allowing for a different provider than the + server's default. + Obtaining an EntityManagerFactory - from JNDI (for example in a Java EE 5 environment), is just a matter + from JNDI (for example in a Java EE 5 environment), is simply a matter of changing the XML configuration: <beans> @@ -1282,12 +1321,12 @@ public class ProductDaoImpl implements ProductDao { </beans> - This assumes standard Java EE 5 bootstrapping, with the Java EE - server autodetecting persistence units (i.e. + This action assumes standard Java EE 5 bootstrapping: the Java + EE server autodetects persistence units (in effect, META-INF/persistence.xml files in application jars) and persistence-unit-ref entries in the Java EE - deployment descriptor (e.g. web.xml) defining - environment naming context locations for those persistence + deployment descriptor (for example, web.xml) and + defines environment naming context locations for those persistence units. In such a scenario, the entire persistence unit deployment, @@ -1298,37 +1337,40 @@ public class ProductDaoImpl implements ProductDao { EntityManager transactions are integrated with the server's JTA subsystem. Spring merely uses the obtained EntityManagerFactory, passing it on to - application objects via dependency injection, and managing - transactions for it (typically through - JtaTransactionManager). + application objects through dependency injection, and managing + transactions for the persistence unit, + typically through JtaTransactionManager. - Note that, in case of multiple persistence units used in the - same application, the bean names of such a JNDI-retrieved persistence - units should match the persistence unit names that the application - uses to refer to them (e.g. in @PersistenceUnit and - @PersistenceContext annotations). - - Use this option when deploying to a Java EE 5 server. - Check your server's documentation on how to deploy a custom JPA - provider into your server, allowing for a different provider than the - server's default. + If multiple persistence units are used in the same application, + the bean names of such JNDI-retrieved persistence units should match + the persistence unit names that the application uses to refer to them, + for example, in @PersistenceUnit and + @PersistenceContext annotations.
<classname>LocalContainerEntityManagerFactoryBean</classname> + + Use this option for full JPA capabilities in a Spring-based + application environment. This includes web containers such as Tomcat + as well as stand-alone applications and integration tests with + sophisticated persistence requirements. + + The LocalContainerEntityManagerFactoryBean gives full control over EntityManagerFactory configuration and is appropriate for environments where fine-grained customization is required. The - LocalContainerEntityManagerFactoryBean will - create a PersistenceUnitInfo based on - the persistence.xml file, the supplied - dataSourceLookup strategy and the specified + LocalContainerEntityManagerFactoryBean creates + a PersistenceUnitInfo instancebased + on the persistence.xml file, the supplied + dataSourceLookup strategy, and the specified loadTimeWeaver. It is thus possible to work with - custom DataSources outside of JNDI and to control the weaving - process. + custom data sources outside of JNDI and to control the weaving + process. The following example shows a typical bean definition for a + LocalContainerEntityManagerFactoryBean: <beans> @@ -1341,8 +1383,8 @@ public class ProductDaoImpl implements ProductDao { </beans> - A typical persistence.xml file looks as - follows: + The following example shows a typical + persistence.xml file: <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> @@ -1353,97 +1395,97 @@ public class ProductDaoImpl implements ProductDao { </persistence> - NOTE: The "exclude-unlisted-classes" element always - indicates that NO scanning for annotated entity classes is supposed to - happen, in order to support the - <exclude-unlisted-classes/> shortcut. This is - in line with the JPA specification (which suggests that shortcut) but - unfortunately in conflict with the JPA XSD (which implies "false" for - that shortcut). As a consequence, - "<exclude-unlisted-classes> false - </exclude-unlisted-classes/>" is not supported! Simply - omit the "exclude-unlisted-classes" element if you would like entity - class scanning to actually happen. + + The exclude-unlisted-classes element always + indicates that no scanning for annotated entity + classes is supposed to occur, in order to support the + <exclude-unlisted-classes/> shortcut. This is in + line with the JPA specification, which suggests that shortcut, but + unfortunately is in conflict with the JPA XSD, which implies + false for that shortcut. Consequently, + <exclude-unlisted-classes> false + </exclude-unlisted-classes/> is not supported. Simply + omit the exclude-unlisted-classes element if you want + entity class scanning to occur. + - This is the most powerful JPA setup option, allowing for - flexible local configuration within the application. It supports links - to an existing JDBC DataSource, - supports both local and global transactions, etc. However, it also - imposes requirements onto the runtime environment, such as the - availability of a weaving-capable ClassLoader if the persistence - provider demands byte-code transformation. + Using the + LocalContainerEntityManagerFactoryBean is the + most powerful JPA setup option, allowing for flexible local + configuration within the application. It supports links to an existing + JDBC DataSource, supports both local + and global transactions, and so on. However, it also imposes + requirements on the runtime environment, such as the availability of + a weaving-capable class loader if the persistence provider demands + byte-code transformation. - Note that this option may conflict with the built-in JPA - capabilities of a Java EE 5 server. So when running in a full Java EE - 5 environment, consider obtaining your - EntityManagerFactory from JNDI. - Alternatively, specify a custom "persistenceXmlLocation" on your + This option may conflict with the built-in JPA capabilities of a + Java EE 5 server. In a full Java EE 5 environment, consider obtaining + your EntityManagerFactory from JNDI. + Alternatively, specify a custom + persistenceXmlLocation on your LocalContainerEntityManagerFactoryBean - definition, e.g. "META-INF/my-persistence.xml", and only include a - descriptor with that name in your application jar files. Since the - Java EE 5 server will only look for default - META-INF/persistence.xml files, it will ignore such + definition, for example, META-INF/my-persistence.xml, and only include + a descriptor with that name in your application jar files. Because the + Java EE 5 server only looks for default + META-INF/persistence.xml files, it ignores such custom persistence units and hence avoid conflicts with a Spring-driven JPA setup upfront. (This applies to Resin 3.1, for example.) - Use this option for full JPA capabilities in a - Spring-based application environment. This includes web containers - such as Tomcat as well as standalone applications and integration - tests with sophisticated persistence requirements. - When is load-time weaving required? - Not all JPA providers impose the need of a JVM agent - (Hibernate being an example). If your provider does not require an - agent or you have other alternatives (for example applying - enhancements at build time through a custom compiler or an ant task) - the load-time weaver should not be + Not all JPA providers require a JVM agent ; Hibernate is an + example of one that does not. If your provider does not require an + agent or you have other alternatives, such as applying enhancements + at build time through a custom compiler or an ant task, the + load-time weaver should not be used. The LoadTimeWeaver interface is a Spring-provided class that allows JPA ClassTransformer instances to be - plugged in a specific manner depending on the environment (web - container/application server). Hooking - ClassTransformers through a Java 5 + Hooking ClassTransformers through a Java 5 agent - is typically not efficient - the agents work against the + typically is not efficient. The agents work against the entire virtual machine and inspect - every class that is loaded - something that is - typically undesirable in a production server enviroment. + every class that is loaded, which is usually + undesirable in a production server environment. Spring provides a number of LoadTimeWeaver implementations for various environments, allowing ClassTransformer instances to be - applied only per ClassLoader and not per + applied only per class loader and not per VM. The following sections will discuss typical JPA weaving setup on - Tomcat as well as using Spring's VM agent. See the AOP chapter section - entitled for details on how to - set up general load-time weaving, covering Tomcat and the VM agent as - well as WebLogic, OC4J, GlassFish and Resin. + Tomcat and with Spring's VM agent. See in the AOP chapter for details on how + to set up general load-time weaving with Tomcat, the VM agent, + WebLogic, OC4J, GlassFish, and Resin.
Tomcat load-time weaving setup (5.0+) Apache Tomcat's - default ClassLoader does not support class transformation but allows - custom ClassLoaders to be used. Spring offers the - TomcatInstrumentableClassLoader (inside the + default class loader does not support class transformation but does + allow the use of custom class loaders. Spring offers the + TomcatInstrumentableClassLoader (in the org.springframework.instrument.classloading.tomcat - package) which extends the Tomcat ClassLoader - (WebappClassLoader) and allows JPA - ClassTransformer instances to 'enhance' all - classes loaded by it. In short, JPA transformers will be applied - only inside a specific web application (which uses the - TomcatInstrumentableClassLoader). + package), which extends the Tomcat class loader + (WebappClassLoader), and allows JPA + ClassTransformer instances to enhance all + classes loaded by it. In short, JPA transformers are applied only + inside a specific web application that uses the + TomcatInstrumentableClassLoader. - In order to use the custom ClassLoader on: + To use the custom class loader on: @@ -1453,14 +1495,14 @@ public class ProductDaoImpl implements ProductDao { Copy spring-tomcat-weaver.jar into - $CATALINA_HOME/server/lib (where + $CATALINA_HOME/server/lib,where $CATALINA_HOME represents the root of the - Tomcat installation). + Tomcat installation. - Instruct Tomcat to use the custom ClassLoader (instead - of the default one) by editing the web application context + Instruct Tomcat to use the custom class loader instead + of the default one by editing the web application context file: <Context path="/myWebApp" docBase="/my/webApp/location"> @@ -1468,31 +1510,34 @@ public class ProductDaoImpl implements ProductDao { </Context> Tomcat 5.0.x and 5.5.x series support several context - locations: server configuration file + locations: server + configuration file ($CATALINA_HOME/conf/server.xml), the default context configuration ($CATALINA_HOME/conf/context.xml) that - affects all deployed web applications and per-webapp - configurations, deployed on the server + affects all deployed web applications and per-web application + configurations, deployed + on the server ($CATALINA_HOME/conf/[enginename]/[hostname]/my-webapp-context.xml) - side or along with the webapp + side or inside the web application (your-webapp.war/META-INF/context.xml). - For efficiency, inside the web-app configuration style is - recommended since only applications which use JPA will use the - custom ClassLoader. See the Tomcat 5.x is recommended + because only applications that use JPA will use the custom c + lass loader. See the Tomcat 5.x documentation for more details about available context locations. - Note that versions prior to 5.5.20 contained a bug in - the XML configuration parsing preventing usage of + Tomcat versions prior to 5.5.20 contained a bug in the + XML configuration parsing that prevented usage of the Loader tag inside - server.xml (no matter if a ClassLoader is - specified or not (be it the official or a custom one). See - Tomcat's bugzilla for server.xml, regardless of whether a class + loader is specified or whether it is the official or a custom + one. See Tomcat's bugzilla for more - details. + details. - If you are using Tomcat 5.5.20+ you can set + In Tomcat 5.5.20 or later, you can set useSystemClassLoaderAsParent to false to fix the problem: <Context path="/myWebApp" docBase="/my/webApp/location"> @@ -1509,42 +1554,44 @@ public class ProductDaoImpl implements ProductDao { Copy spring-tomcat-weaver.jar into - $CATALINA_HOME/lib (where + $CATALINA_HOME/lib, where $CATALINA_HOME represents the root of the - Tomcat installation). + Tomcat installation) - Instruct Tomcat to use the custom ClassLoader (instead - of the default one) by editing the web application context + Instruct Tomcat to use the custom class loader (instead + of the default) by editing the web application context file: <Context path="/myWebApp" docBase="/my/webApp/location"> <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/> </Context> - Tomcat 6.0.x (similar to 5.0.x/5.5.x) series support - several context locations: server configuration file + The Tomcat 6.0.x (similar to 5.0.x/5.5.x) series + supports several context locations: server configuration file ($CATALINA_HOME/conf/server.xml), the default context configuration ($CATALINA_HOME/conf/context.xml) that - affects all deployed web applications and per-webapp - configurations, deployed on the server + affects all deployed web applications and per-web application + configurations, deployed + on the server ($CATALINA_HOME/conf/[enginename]/[hostname]/my-webapp-context.xml) - side or along with the webapp + side or inside the web application (your-webapp.war/META-INF/context.xml). - For efficiency, inside the web-app configuration style is - recommended since only applications which use JPA will use the - custom ClassLoader. See the Tomcat 5.x is + recommended because only applications that use JPA will use + the custom class loader. See the Tomcat 6.0.x documentation for more details about available context locations. - The last step required on all Tomcat versions, is to use the - appropriate the LoadTimeWeaver when - configuring + The last step required on all Tomcat versions is to use the + appropriate LoadTimeWeaver when you + configure LocalContainerEntityManagerFactoryBean: <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> @@ -1554,29 +1601,31 @@ public class ProductDaoImpl implements ProductDao { </bean> Using this technique, JPA applications relying on - instrumentation, can run in Tomcat without the need of an agent. - This is important especially when hosting applications which rely on - different JPA implementations since the JPA transformers are applied - only at ClassLoader level and thus, are isolated from each - other. + instrumentation, and can run in Tomcat without needing an agent. + This is important especially when Tomcat is hosting applications + that rely on different JPA implementations because the JPA + transformers are applied only at class loader level and thus are + isolated from each other. - If TopLink Essentials is being used a JPA provider under - Tomcat, please place the toplink-essentials jar under + If you use TopLink Essentials as a JPA provider under + Tomcat, place the toplink-essentials JAR under $CATALINA_HOME/shared/lib folder instead of - your war. + inside your war.
- General load-time weaving using the VM agent + General load-time weaving with the VM agent - For environments where class instrumentation is required but - are not supported by the existing LoadTimeWeaver implementations, a - JDK agent can be the only solution. For such cases, Spring provides - InstrumentationLoadTimeWeaver which requires - a Spring-specific (but very general) VM agent (spring-agent.jar): + For environments that require class instrumentation but are + not supported by the existing LoadTimeWeaver + implementations, + a JDK agent can be the only solution. For such cases, Spring + provides InstrumentationLoadTimeWeaver, which + requires a Spring-specific (but very general) VM agent, spring-agent.jar: <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="loadTimeWeaver"> @@ -1584,8 +1633,8 @@ public class ProductDaoImpl implements ProductDao { </property> </bean> - Note that the virtual machine has to be started with the - Spring agent, by supplying the following JVM options: + You must start the virtual machine with the Spring agent, by + supplying the following JVM options: -javaagent:/path/to/spring-agent.jar
@@ -1593,17 +1642,17 @@ public class ProductDaoImpl implements ProductDao {
Context-wide load-time weaver setup - Since Spring 2.5, a context-wide - LoadTimeWeaver can be configured - using the context:load-time-weaver configuration - element. Such a 'global' weaver will be picked up by all JPA + In Spring 2.5 and later, you can configure a context-wide + LoadTimeWeaver using the + context:load-time-weaver configuration element. + Such a global weaver is picked up by all JPA LocalContainerEntityManagerFactoryBeans automatically. This is the preferred way of setting up a load-time weaver, delivering autodetection of the platform (WebLogic, OC4J, GlassFish, - Tomcat, Resin, VM agent) as well as automatic propagation of the - weaver to all weaver-aware beans. + Tomcat, Resin, or VM agent) and automatic propagation of the weaver + to all weaver-aware beans. <context:load-time-weaver/> @@ -1611,10 +1660,9 @@ public class ProductDaoImpl implements ProductDao { ... </bean> - See the section entitled - for details on how to set up general load-time weaving, covering - Tomcat and the VM agent as well as WebLogic, OC4J, GlassFish and - Resin. + See for details on how to + set up general load-time weaving, covering Tomcat and the VM agent + as well as WebLogic, OC4J, GlassFish and Resin.
@@ -1622,15 +1670,15 @@ public class ProductDaoImpl implements ProductDao { Dealing with multiple persistence units For applications that rely on multiple persistence units - locations (stored in various jars in the classpath for example), + locations, stored in various JARS in the classpath, for example, Spring offers the PersistenceUnitManager to act as a - central repository and avoid the (potentially expensive) persistence - units discovery process. The default implementation allows multiple - locations to be specified (by default, the classpath is searched for - 'META-INF/persistence.xml' files) which are - parsed and later on retrieved through the persistence unit - name: + central repository and to avoid the persistence units discovery + process, which can be expensive. The default implementation allows + multiple locations to be specified that are parsed and later retrieved + through the persistence unit name. (By default, the classpath is + searched for META-INF/persistence.xml + files.) <bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"> <property name="persistenceXmlLocation"> @@ -1654,14 +1702,16 @@ public class ProductDaoImpl implements ProductDao { <property name="persistenceUnitManager" ref="pum"/> </bean> - Note that the default implementation allows customization of the - persistence unit infos before feeding them to the JPA provider - declaratively through its properties (which affect - all hosted units) or programmatically, through - the PersistenceUnitPostProcessor (which - allows persistence unit selection). If no + The default implementation allows customization of the + PersistenceUnitInfo instances, + before they are fed to the JPA provider, declaratively through its + properties, + which affect all hosted units, or + programmatically, through the + PersistenceUnitPostProcessor, which + allows persistence unit selection. If no PersistenceUnitManager is specified, - one will be created and used internally by + one is created and used internally by LocalContainerEntityManagerFactoryBean.
@@ -1670,28 +1720,30 @@ public class ProductDaoImpl implements ProductDao { Implementing DAOs based on plain JPA - While EntityManagerFactory + Although EntityManagerFactory instances are thread-safe, EntityManager instances are not. The - injected JPA EntityManager behave just - like an EntityManager fetched from an + injected JPA EntityManager behaves like + an EntityManager fetched from an application server's JNDI environment, as defined by the JPA - specification. It will delegate all calls to the current transactional - EntityManager, if any; else, it will - fall back to a newly created - EntityManager per operation, making it - thread-safe. + specification. It delegates all calls to the current transactional + EntityManager, if any; otherwise, it + falls back to a newly created + EntityManager per operation, in effect + making its usage thread-safe. - It is possible to write code against the plain JPA without using - any Spring dependencies, using an injected + It is possible to write code against the plain JPA without any + Spring dependencies, by using an injected EntityManagerFactory or - EntityManager. Note that Spring can - understand @PersistenceUnit and + EntityManager. Spring can understand + @PersistenceUnit and @PersistenceContext annotations both at field and method level if a PersistenceAnnotationBeanPostProcessor is - enabled. A corresponding DAO implementation might look like this: + enabled. A plain JPA DAO implementation using the + @PersistenceUnit annotation might + look like this: public class ProductDaoImpl implements ProductDao { @@ -1731,14 +1783,14 @@ public class ProductDaoImpl implements ProductDao { </beans> - Note: As alternative to defining a + As an alternative to defining a PersistenceAnnotationBeanPostProcessor - explicitly, consider using Spring 2.5's + explicitly, consider using the Spring context:annotation-config XML element in your - application context configuration. This will automatically register all - of Spring's standard post-processors for annotation-based configuration - (including CommonAnnotationBeanPostProcessor - etc). + application context configuration. Doing so automatically registers all + Spring standard post-processors for annotation-based configuration, + including CommonAnnotationBeanPostProcessor and + so on. <beans> @@ -1749,11 +1801,11 @@ public class ProductDaoImpl implements ProductDao { </beans> - The main issue with such a DAO is that it always creates a new - EntityManager via the factory. This can - be easily overcome by requesting a transactional + The main problem with such a DAO is that it always creates a new + EntityManager through the factory. You + can avoid this by requesting a transactional EntityManager (also called "shared - EntityManager", since it is a shared, thread-safe proxy for the actual + EntityManager" because it is a shared, thread-safe proxy for the actual transactional EntityManager) to be injected instead of the factory: @@ -1769,32 +1821,33 @@ public class ProductDaoImpl implements ProductDao { } } - Note that the @PersistenceContext annotation - has an optional attribute type, which defaults to + The @PersistenceContext annotation has an + optional attribute type, which defaults to PersistenceContextType.TRANSACTION. This default is - what you need to receive a "shared EntityManager" proxy. The - alternative, PersistenceContextType.EXTENDED, is a - completely different affair: This results in a so-called "extended - EntityManager", which is not thread-safe and hence - must not be used in a concurrently accessed component such as a - Spring-managed singleton bean. Extended EntityManagers are only supposed - to be used in stateful components that, for example, reside in a - session, with the lifecycle of the EntityManager not tied to a current - transaction but rather being completely up to the application. + what you need to receive a shared EntityManager proxy. The alternative, + PersistenceContextType.EXTENDED, is a completely + different affair: This results in a so-called extended EntityManager, + which is not thread-safe and hence must not be used + in a concurrently accessed component such as a Spring-managed singleton + bean. Extended EntityManagers are only supposed to be used in stateful + components that, for example, reside in a session, with the lifecycle of + the EntityManager not tied to a current transaction but rather being + completely up to the application. - Method and Field level Injection + Method- and field-level Injection Annotations that indicate dependency injections (such as @PersistenceUnit and @PersistenceContext) can be applied on field or - methods inside a class, therefore the expression "method/field level - injection". Field-level annotations are concise and easier to use - while method-level allow for further processing of the injected - dependency. In both cases the member visibility (public, protected, - private) does not matter. + methods inside a class, hence the expressions method-level + injection and field-level injection. + Field-level annotations are concise and easier to use while + method-level allows for further processing of the injected dependency. + In both cases the member visibility (public, protected, private) does + not matter. - What about class level annotations? + What about class-level annotations? On the Java EE 5 platform, they are used for dependency declaration and not for resource injection. @@ -1802,32 +1855,32 @@ public class ProductDaoImpl implements ProductDao { The injected EntityManager is Spring-managed (aware of the ongoing transaction). It is important to - note that even though the new implementation prefers method level - injection (of an EntityManager instead of - an EntityManagerFactory), no change is - required in the application context XML due to annotation usage. + note that even though the new DAO implementation uses method level + injection of an EntityManager instead of + an EntityManagerFactory, no change is + required in the application context XML due to annotation usage.
- The main advantage of this DAO style is that it depends on Java - Persistence API; no import of any Spring class is required. Moreover, as - the JPA annotations are understood, the injections are applied - automatically by the Spring container. This is of course appealing from - a non-invasiveness perspective, and might feel more natural to JPA + The main advantage of this DAO style is that it only depends on + Java Persistence API; no import of any Spring class is required. + Moreover, as the JPA annotations are understood, the injections are + applied automatically by the Spring container. This is appealing from a + non-invasiveness perspective, and might feel more natural to JPA developers.
Transaction Management + + You are strongly encouraged to read if you have not done so, to get a + more detailed coverage of Spring's declarative transaction + support. + + To execute service operations within transactions, you can use Spring's common declarative transaction facilities. For example: - - You are strongly encouraged to read the - section entitled if you - have not done so to get a more detailed coverage of Spring's - declarative transaction support. - - <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" @@ -1882,38 +1935,40 @@ public class ProductDaoImpl implements ProductDao { JpaTransactionManager and subclasses of AbstractEntityManagerFactoryBean support a custom JpaDialect, to be passed into the - "jpaDialect" bean property. In such a scenario, the DAOs won't receive - an EntityManagerFactory reference but - rather a full JpaTemplate instance instead (for - example, passed into JpaDaoSupport's - "jpaTemplate" property). A JpaDialect + jpaDialect bean property. In such a scenario, the + DAOs do not receive an + EntityManagerFactory reference but rather + a full JpaTemplate instance (for example, + passed + into the jpaTemplate property of + JpaDaoSupport). A JpaDialect implementation can enable some advanced features supported by Spring, usually in a vendor-specific manner: - applying specific transaction semantics (such as custom + Applying specific transaction semantics such as custom isolation level or transaction timeout) - retrieving the transactional JDBC - Connection (for exposure to - JDBC-based DAOs) + Retrieving the transactional JDBC + Connection for exposure to JDBC-based + DAOs) - advanced translation of + Advanced translation of PersistenceExceptions to Spring DataAccessExceptions This is particularly valuable for special transaction semantics - and for advanced translation of exception. Note that the default - implementation used (DefaultJpaDialect) doesn't - provide any special capabilities and if the above features are required, - the appropriate dialect has to be specified. + and for advanced translation of exception. The default implementation + used (DefaultJpaDialect) does not provide any + special capabilities and if the above features are required, you have to + specify the appropriate dialect. See the JpaDialect Javadoc for more details of its operations and how they are used within Spring's JPA @@ -1925,31 +1980,60 @@ public class ProductDaoImpl implements ProductDao { iBATIS SQL Maps The iBATIS support in the Spring Framework much resembles the JDBC - support in that it supports the same template style programming and just - as with JDBC or other ORM technologies, the iBATIS support works with - Spring's exception hierarchy and let's you enjoy the all IoC features - Spring has. + support in that it supports the same template style programming, and as + with JDBC and other ORM technologies, the iBATIS support works with + Spring's exception hierarchy and lets you enjoy Spring's IoC + features. Transaction management can be handled through Spring's standard - facilities. There are no special transaction strategies for iBATIS, as - there is no special transactional resource involved other than a JDBC + facilities. No special transaction strategies are necessary for iBATIS, + because no special transactional resource involved other than a JDBC Connection. Hence, Spring's standard JDBC DataSourceTransactionManager or JtaTransactionManager are perfectly sufficient. - Spring supports iBatis 2.x. The iBatis 1.x support classes were - moved to the Spring Modules project as of Spring 2.0, and you are - directed there for documentation. + Spring supports iBATIS 2.x. The iBATIS 1.x support classes are no + longer provided.
Setting up the <classname>SqlMapClient</classname> - If we want to map the previous Account class with iBATIS 2.x we + Using iBATIS SQL Maps involves creating SqlMap configuration files + containing statements and result maps. Spring takes care of loading + those using the SqlMapClientFactoryBean. For the + examples we will be using the following Account + class: + + public class Account { + + private String name; + private String email; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } +} + + To map this Account class with iBATIS 2.x we need to create the following SQL map - 'Account.xml': + Account.xml: <sqlMap namespace="Account"> @@ -1979,14 +2063,15 @@ public class ProductDaoImpl implements ProductDao { </sqlMapConfig> Remember that iBATIS loads resources from the class path, so be - sure to add the 'Account.xml' file to the class + sure to add theAccount.xml file to the class path. We can use the SqlMapClientFactoryBean in the Spring container. Note that with iBATIS SQL Maps 2.x, the JDBC DataSource is usually specified on the SqlMapClientFactoryBean, which enables lazy - loading. + loading. This is the configuration needed for these bean + definitions: <beans> @@ -2038,14 +2123,14 @@ public class ProductDaoImpl implements ProductDao { </beans> - Note that a SqlMapTemplate instance could - also be created manually, passing in the SqlMapClient - as constructor argument. The SqlMapClientDaoSupport - base class simply pre-initializes a + An SqlMapTemplate instance can also be + created manually, passing in the SqlMapClient as + constructor argument. The SqlMapClientDaoSupport base + class simply preinitializes a SqlMapClientTemplate instance for us. - The SqlMapClientTemplate also offers a - generic execute method, taking a custom + The SqlMapClientTemplate offers a generic + execute method, taking a custom SqlMapClientCallback implementation as argument. This can, for example, be used for batching: @@ -2065,8 +2150,8 @@ public class ProductDaoImpl implements ProductDao { In general, any combination of operations offered by the native SqlMapExecutor API can be used in such a callback. - Any SQLException thrown will automatically get - converted to Spring's generic DataAccessException + Any thrown SQLException is converted automatically to + Spring's generic DataAccessException hierarchy.
@@ -2075,8 +2160,8 @@ public class ProductDaoImpl implements ProductDao { DAOs can also be written against plain iBATIS API, without any Spring dependencies, directly using an injected - SqlMapClient. A corresponding DAO implementation - looks like as follows: + SqlMapClient. The following example shows a + corresponding DAO implementation: public class SqlMapAccountDao implements AccountDao { @@ -2105,12 +2190,14 @@ public class ProductDaoImpl implements ProductDao { } } - In such a scenario, the SQLException thrown by - the iBATIS API needs to be handled in a custom fashion: usually, - wrapping it in your own application-specific DAO exception. Wiring in - the application context would still look like before, due to the fact - that the plain iBATIS-based DAO still follows the Dependency Injection - pattern: + In this scenario, you need to handle the + SQLException thrown by the iBATIS API in a custom + fashion, usually by wrapping it in your own application-specific DAO + exception. Wiring in the application context would still look like it + does in the example for the + SqlMapClientDaoSupport, + due to the fact that the plain iBATIS-based DAO still follows the + dependency injection pattern: <beans>