@ -142,8 +142,8 @@
@@ -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.
</para>
case of JDBC and applying AOP interceptors for the ORM
technologies. </para>
<para > The infrastructure cares for proper resource handling, and for
appropriate conversion of specific API exceptions to an unchecked
@ -155,7 +155,7 @@
@@ -155,7 +155,7 @@
<classname > DataAccessException</classname> 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. </para>
same exception translation benefits.</para>
<para > When it comes to transaction management the
<classname > JdbcTemplate</classname> class hooks in to the Spring
@ -164,7 +164,7 @@
@@ -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 <xref
linkend="transaction" /> chapter. </para>
linkend="transaction" /> chapter.</para>
</section>
<section id= "orm-exception-translation" >
@ -382,6 +382,140 @@ public class ProductDaoImpl implements ProductDao {
@@ -382,6 +382,140 @@ public class ProductDaoImpl implements ProductDao {
transactions.</para>
</section>
<section id= "orm-hibernate-tx-declarative" >
<title > Declarative transaction demarcation</title>
<para > 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.</para>
<note >
<para > You are <emphasis > strongly</emphasis> encouraged to read the
section entitled <xref linkend= "transaction-declarative" /> if you
have not done so already prior to continuing.</para>
</note>
<para > Furthermore, transaction semantics like propagation behavior and
isolation level can be changed in a configuration file and do not affect
the business service implementations.</para>
<programlisting language= "xml" > < ?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">
<lineannotation > < !-- <interfacename > SessionFactory</interfacename> , <interfacename > DataSource</interfacename> , etc. omitted --> </lineannotation>
< 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> </programlisting>
<programlisting language= "java" > public class ProductServiceImpl implements ProductService {
private ProductDao productDao;
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
<lineannotation > // notice the absence of transaction demarcation code in this method</lineannotation>
<lineannotation > // Spring's declarative transaction infrastructure will be demarcating transactions on your behalf </lineannotation>
public void increasePriceOfAllProductsInCategory(final String category) {
List productsToChange = this.productDao.loadProductsByCategory(category);
<lineannotation > // ...</lineannotation>
}
}</programlisting>
<para > 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.</para>
<programlisting language= "java" > 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);
<lineannotation > // ...</lineannotation>
}
@Transactional(readOnly = true)
public List< Product> findAllProducts() {
return this.productDao.findAllProducts();
}
}</programlisting>
<para > 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.</para>
<programlisting language= "xml" > < ?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">
<lineannotation > < !-- <interfacename > SessionFactory</interfacename> , <interfacename > DataSource</interfacename> , etc. omitted --> </lineannotation>
< 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> </programlisting>
</section>
<section id= "orm-hibernate-tx-programmatic" >
<title > Programmatic transaction demarcation</title>
@ -435,59 +569,6 @@ public class ProductDaoImpl implements ProductDao {
@@ -435,59 +569,6 @@ public class ProductDaoImpl implements ProductDao {
);
}
}</programlisting>
</section>
<section id= "orm-hibernate-tx-declarative" >
<title > Declarative transaction demarcation</title>
<para > 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.</para>
<programlisting language= "xml" > < 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> <lineannotation > < !-- the transaction interceptor (configured elsewhere) --> </lineannotation>
< /list>
< /property>
< /bean>
< /beans> </programlisting>
<programlisting language= "java" > public class ProductServiceImpl implements ProductService {
private ProductDao productDao;
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
<lineannotation > // notice the absence of transaction demarcation code in this method</lineannotation>
<lineannotation > // Spring's declarative transaction infrastructure will be demarcating transactions on your behalf </lineannotation>
public void increasePriceOfAllProductsInCategory(final String category) {
List productsToChange = this.productDao.loadProductsByCategory(category);
<lineannotation > // ...</lineannotation>
}
}</programlisting>
<para > Spring's <classname > TransactionInterceptor</classname> allows any
checked application exception to be thrown with the callback code, while
@ -499,55 +580,6 @@ public class ProductDaoImpl implements ProductDao {
@@ -499,55 +580,6 @@ public class ProductDaoImpl implements ProductDao {
<classname > TransactionStatus</classname> ).
<classname > TransactionInterceptor</classname> behaves the same way by
default but allows configurable rollback policies per method.</para>
<para > The following higher level approach to declarative transactions
doesn't use the <classname > ProxyFactoryBean</classname> , and as such may
be easier to use if you have a large number of service objects that you
wish to make transactional.</para>
<note >
<para > You are <emphasis > strongly</emphasis> encouraged to read the
section entitled <xref linkend= "transaction-declarative" /> if you
have not done so already prior to continuing.</para>
</note>
<programlisting language= "xml" > < ?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">
<lineannotation > < !-- <interfacename > SessionFactory</interfacename> , <interfacename > DataSource</interfacename> , etc. omitted --> </lineannotation>
< 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> </programlisting>
</section>
<section id= "orm-hibernate-tx-strategies" >
@ -633,26 +665,24 @@ public class ProductDaoImpl implements ProductDao {
@@ -633,26 +665,24 @@ public class ProductDaoImpl implements ProductDao {
< property name="sessionFactory" ref="mySessionFactory2"/>
< /bean>
<lineannotation > < !-- this shows the Spring 1.x style of declarative transaction configuration --> </lineannotation>
<lineannotation > < !-- it is totally supported, 100% legal in Spring 2.x, but see also above for the sleeker, Spring 2.0 style --> </lineannotation>
< 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> </programlisting>
<para > Both <classname > HibernateTransactionManager</classname> and
@ -1078,6 +1108,13 @@ public class ProductDaoImpl implements ProductDao {
@@ -1078,6 +1108,13 @@ public class ProductDaoImpl implements ProductDao {
<para > To execute service operations within transactions, you can use
Spring's common declarative transaction facilities. For example:</para>
<note >
<para > You are <emphasis > strongly</emphasis> encouraged to read the
section entitled <xref linkend= "transaction-declarative" /> if you
have not done so to get a more detailed coverage of Spring's
declarative transaction support.</para>
</note>
<programlisting language= "xml" > < ?xml version="1.0" encoding="UTF-8"?>
< beans
xmlns="http://www.springframework.org/schema/beans"
@ -1086,11 +1123,11 @@ public class ProductDaoImpl implements ProductDao {
@@ -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 {
@@ -1755,10 +1792,10 @@ public class ProductDaoImpl implements ProductDao {
<literal > @PersistenceUnit</literal> and
<literal > @PersistenceContext</literal> ) 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.</para>
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.</para>
<para > What about class level annotations?</para>
@ -1832,6 +1869,13 @@ public class ProductDaoImpl implements ProductDao {
@@ -1832,6 +1869,13 @@ public class ProductDaoImpl implements ProductDao {
<para > To execute service operations within transactions, you can use
Spring's common declarative transaction facilities. For example:</para>
<note >
<para > You are <emphasis > strongly</emphasis> encouraged to read the
section entitled <xref linkend= "transaction-declarative" /> if you have
not done so to get a more detailed coverage of Spring's declarative
transaction support.</para>
</note>
<programlisting language= "xml" > < ?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 {
@@ -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"/>