diff --git a/spring-framework-reference/src/dao.xml b/spring-framework-reference/src/dao.xml index 65900b4b51..29cc960fb8 100644 --- a/spring-framework-reference/src/dao.xml +++ b/spring-framework-reference/src/dao.xml @@ -89,7 +89,7 @@ public class SomeMovieFinder implements MovieFinder { @PersistenceContext annotations. Here is an example for a JPA repository: - @Repository public class JpaMovieFinder implements MovieFinder { @PersistenceContext @@ -97,12 +97,12 @@ public class JpaMovieFinder implements MovieFinder { // ... -}]]> +} If you are using the classic Hibernate APIs than you can inject the SessionFactory: - @Repository public class HibernateMovieFinder implements MovieFinder { private SessionFactory sessionFactory; @@ -114,7 +114,7 @@ public class HibernateMovieFinder implements MovieFinder { // ... -}]]> +} Last example we will show here is for typical JDBC support. You would have the DataSource injected into an @@ -123,7 +123,7 @@ public class HibernateMovieFinder implements MovieFinder { like SimpleJdbcCall etc using this DataSource. - @Repository public class JdbcMovieFinder implements MovieFinder { private JdbcTemplate jdbcTemplate; @@ -135,6 +135,14 @@ public class JdbcMovieFinder implements MovieFinder { // ... -}]]> +} + + + Please see the specific coverage of each persistence technology + for details on how to configure the application context to take + advantage of these annotations. + + + - \ No newline at end of file + diff --git a/spring-framework-reference/src/orm.xml b/spring-framework-reference/src/orm.xml index 51441edcf6..240f30663c 100644 --- a/spring-framework-reference/src/orm.xml +++ b/spring-framework-reference/src/orm.xml @@ -142,8 +142,8 @@ 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. - + case of JDBC and applying AOP interceptors for the ORM + technologies. The infrastructure cares for proper resource handling, and for appropriate conversion of specific API exceptions to an unchecked @@ -155,7 +155,7 @@ 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. + same exception translation benefits. When it comes to transaction management the JdbcTemplate class hooks in to the Spring @@ -164,7 +164,7 @@ 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. + linkend="transaction" /> chapter.
@@ -382,6 +382,140 @@ public class ProductDaoImpl implements ProductDao { transactions.
+
+ Declarative transaction demarcation + + We recommended that you use Spring's declarative transaction + support, which essentially enables you to replace explicit transaction + demarcation API calls in your Java code with an AOP transaction + interceptor configured in a Spring container. 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. + + + You are strongly encouraged to read the + section entitled if you + have not done so already prior to continuing. + + + Furthermore, transaction semantics like propagation behavior and + isolation level can be changed in a configuration file and do not affect + the business service implementations. + + <?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:aop="http://www.springframework.org/schema/aop" + xmlns:tx="http://www.springframework.org/schema/tx" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/tx + http://www.springframework.org/schema/tx/spring-tx-3.0.xsd + http://www.springframework.org/schema/aop + http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> + + <!-- SessionFactory, DataSource, etc. omitted --> + + <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> + <property name="sessionFactory" ref="sessionFactory"/> + </bean> + + <aop:config> + <aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/> + <aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/> + </aop:config> + + <tx:advice id="txAdvice" transaction-manager="myTxManager"> + <tx:attributes> + <tx:method name="increasePrice*" propagation="REQUIRED"/> + <tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/> + <tx:method name="*" propagation="SUPPORTS" read-only="true"/> + </tx:attributes> + </tx:advice> + + <bean id="myProductService" class="product.SimpleProductService"> + <property name="productDao" ref="myProductDao"/> + </bean> + +</beans> + + public class ProductServiceImpl implements ProductService { + + private ProductDao productDao; + + public void setProductDao(ProductDao productDao) { + this.productDao = productDao; + } + + // notice the absence of transaction demarcation code in this method + // Spring's declarative transaction infrastructure will be demarcating transactions on your behalf + public void increasePriceOfAllProductsInCategory(final String category) { + List productsToChange = this.productDao.loadProductsByCategory(category); + // ... + } +} + + 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. + + public class ProductServiceImpl implements ProductService { + + private ProductDao productDao; + + public void setProductDao(ProductDao productDao) { + this.productDao = productDao; + } + + @Transactional + public void increasePriceOfAllProductsInCategory(final String category) { + List productsToChange = this.productDao.loadProductsByCategory(category); + // ... + } + + @Transactional(readOnly = true) + public List<Product> findAllProducts() { + return this.productDao.findAllProducts(); + } + +} + + 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. + + <?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:aop="http://www.springframework.org/schema/aop" + xmlns:tx="http://www.springframework.org/schema/tx" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/tx + http://www.springframework.org/schema/tx/spring-tx-3.0.xsd + http://www.springframework.org/schema/aop + http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> + + <!-- SessionFactory, DataSource, etc. omitted --> + + <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> + <property name="sessionFactory" ref="sessionFactory"/> + </bean> + + <tx:annotation-driven/> + + <bean id="myProductService" class="product.SimpleProductService"> + <property name="productDao" ref="myProductDao"/> + </bean> + +</beans> +
+
Programmatic transaction demarcation @@ -435,59 +569,6 @@ public class ProductDaoImpl implements ProductDao { ); } } -
- -
- Declarative transaction demarcation - - Alternatively, one can use Spring's declarative transaction - support, which essentially enables you to replace explicit transaction - demarcation API calls in your Java code with an AOP transaction - interceptor configured in a Spring container. 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. Furthermore, transaction semantics like - propagation behavior and isolation level can be changed in a - configuration file and do not affect the business service - implementations. - - <beans> - - <bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> - <property name="sessionFactory" ref="mySessionFactory"/> - </bean> - - <bean id="myProductService" class="org.springframework.aop.framework.ProxyFactoryBean"> - <property name="proxyInterfaces" value="product.ProductService"/> - <property name="target"> - <bean class="product.DefaultProductService"> - <property name="productDao" ref="myProductDao"/> - </bean> - </property> - <property name="interceptorNames"> - <list> - <value>myTxInterceptor</value> <!-- the transaction interceptor (configured elsewhere) --> - </list> - </property> - </bean> - -</beans> - - public class ProductServiceImpl implements ProductService { - - private ProductDao productDao; - - public void setProductDao(ProductDao productDao) { - this.productDao = productDao; - } - - // notice the absence of transaction demarcation code in this method - // Spring's declarative transaction infrastructure will be demarcating transactions on your behalf - public void increasePriceOfAllProductsInCategory(final String category) { - List productsToChange = this.productDao.loadProductsByCategory(category); - // ... - } -} Spring's TransactionInterceptor allows any checked application exception to be thrown with the callback code, while @@ -499,55 +580,6 @@ public class ProductDaoImpl implements ProductDao { TransactionStatus). TransactionInterceptor behaves the same way by default but allows configurable rollback policies per method. - - The following higher level approach to declarative transactions - doesn't use the ProxyFactoryBean, and as such may - be easier to use if you have a large number of service objects that you - wish to make transactional. - - - You are strongly encouraged to read the - section entitled if you - have not done so already prior to continuing. - - - <?xml version="1.0" encoding="UTF-8"?> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:aop="http://www.springframework.org/schema/aop" - xmlns:tx="http://www.springframework.org/schema/tx" - xsi:schemaLocation=" - http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/tx - http://www.springframework.org/schema/tx/spring-tx-2.5.xsd - http://www.springframework.org/schema/aop - http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> - - <!-- SessionFactory, DataSource, etc. omitted --> - - <bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> - <property name="sessionFactory" ref="mySessionFactory"/> - </bean> - - <aop:config> - <aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/> - <aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/> - </aop:config> - - <tx:advice id="txAdvice" transaction-manager="myTxManager"> - <tx:attributes> - <tx:method name="increasePrice*" propagation="REQUIRED"/> - <tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/> - <tx:method name="*" propagation="SUPPORTS" read-only="true"/> - </tx:attributes> - </tx:advice> - - <bean id="myProductService" class="product.SimpleProductService"> - <property name="productDao" ref="myProductDao"/> - </bean> - -</beans>
@@ -633,26 +665,24 @@ public class ProductDaoImpl implements ProductDao { <property name="sessionFactory" ref="mySessionFactory2"/> </bean> - <!-- this shows the Spring 1.x style of declarative transaction configuration --> - <!-- it is totally supported, 100% legal in Spring 2.x, but see also above for the sleeker, Spring 2.0 style --> - <bean id="myProductService" - class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> - <property name="transactionManager" ref="myTxManager"/> - <property name="target"> - <bean class="product.ProductServiceImpl"> - <property name="productDao" ref="myProductDao"/> - <property name="inventoryDao" ref="myInventoryDao"/> - </bean> - </property> - <property name="transactionAttributes"> - <props> - <prop key="increasePrice*">PROPAGATION_REQUIRED</prop> - <prop key="someOtherBusinessMethod">PROPAGATION_REQUIRES_NEW</prop> - <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop> - </props> - </property> + <bean id"myProductService" class="product.ProductServiceImpl"> + <property name="productDao" ref="myProductDao"/> + <property name="inventoryDao" ref="myInventoryDao"/> </bean> + <aop:config> + <aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/> + <aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/> + </aop:config> + + <tx:advice id="txAdvice" transaction-manager="myTxManager"> + <tx:attributes> + <tx:method name="increasePrice*" propagation="REQUIRED"/> + <tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/> + <tx:method name="*" propagation="SUPPORTS" read-only="true"/> + </tx:attributes> + </tx:advice> + </beans> Both HibernateTransactionManager and @@ -1078,6 +1108,13 @@ public class ProductDaoImpl implements ProductDao { 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" @@ -1086,11 +1123,11 @@ public class ProductDaoImpl implements ProductDao { xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-2.5.xsd + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx - http://www.springframework.org/schema/tx/spring-tx-2.5.xsd + http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop - http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> + http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean id="myTxManager" class="org.springframework.orm.jdo.JdoTransactionManager"> <property name="persistenceManagerFactory" ref="myPmf"/> @@ -1755,10 +1792,10 @@ public class ProductDaoImpl implements ProductDao { @PersistenceUnit and @PersistenceContext) can be applied on field or methods inside a class, therefore the expression "method/field level - injection". Field-level annotations concise and easier to use while - method-level allow for processing the injected dependency. In both - cases the member visibility (public, protected, private) does not - matter. + 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. What about class level annotations? @@ -1832,6 +1869,13 @@ public class ProductDaoImpl implements ProductDao { 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" @@ -1839,11 +1883,11 @@ public class ProductDaoImpl implements ProductDao { xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-2.5.xsd + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx - http://www.springframework.org/schema/tx/spring-tx-2.5.xsd + http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop - http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> + http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="myEmf"/>