Spring JDBC & Transaction Support

General

Spring data access uses concept of templates to:

  • provide consistent error handling approach
  • provide consistent api

In the past, your DAOs previously extended base Spring DAO classes – this approach is no longer used/recommended (Spring 3.x +) –  use plain annotated POJOs with @Repository annotation.

New Terminology:

  • Repository == DAO

Recommendations

  • one template instance per Repository – Template code is threadsafe, but shared usage (between DAOs/Repositories) would result in blocking calls and reduced performance
  • instead create Template from a Factory, or better still, configure with scope=”prototype”

Exception Handling (in Spring’s View)

  • Checked Exceptions – force developers to add additional code to handle exceptions, bad from the point of view of tight coupling
  • Unchecked Exceptions – can be passed up hierarchy to suitable place to handle, without unnecessary throws clauses
  • Spring framework always uses Unchecked/Runtime Exceptions

Spring Data Access Base Exception

  • DataAccessException -manly subtypes, for example, DataIntegrityViolationException

JDBC Namespace for xml Config

  • provides shortcut config for creating/defining jdbc data access
  • useful for development and testing, provides embedded database support (eg H2)
  • <jdbc:embedded-database…>
  • <jdbc:initialize-database …> – allows running f sql setup scripts

Verbocity of JDBC api approach together with Checked exceptions is simplified by using JDBCTemplate to handle the plumbing, allow using to focus on just what is important, eg the SQL itself and executing code

JDBC Repositories

  • Implement your business interface
  • Annotate with @Repository
  • Inject DataSource in Repository constructor
  • Constructor creates new JdbcTemplate instance from passed DataSource
@Transactional
@Repository
public class ExampleRespositoryImpl implements ExampleRepository
{
    private JdbcTemplate jdbcTemplate;

    public ExampleRespositoryImpl(DataSource datasource)
    {
        this.jdbcTemplate(new JndiTemplate(datasource));
    }
}

Config shortcuts

    • lookup Datasource using:
<jee:jndi-lookup id="datasource" jndi-name="java:/comp/env/jdbc/name"/>

JdbcTemplate.queryForMap()

  • returns single row with columns as keys in the map

JdbcTemplate.queryForList()

  • returns List of Maps (as above)

Spring Container Transaction Support

Configure PlatformTransactionManger according to container and/or persistence technology being used:

e.g:

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/> 

<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

Other PlatformTransactionMangerImplementations (see here for full list):

  • JtaTransactionManager – if using container provided JTA implementation
  • WebLogicJtaTransactionManager – use Weblogic’s transaction manager
  • JpaTransactionManager – use with JPA
  • HibernateTransactionManager – use with Hibernate

Enable Annotation based transaction declarations:

<tx:annotation-driven/>

@Transactional annotation can be at class level or individual method level

AOP based transactional configuration

Add transaction behavior by matching beans/methods transactional based on patterns: (example config from Spring manual : http://static.springsource.org/spring/docs/3.1.2.RELEASE/spring-framework-reference/html/transaction.html)

<aop:config>
  <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager"> 
  <tx:attributes> 
    <!-- all methods starting with 'get' are read-only --> 
    <tx:method name="get*" read-only="true"/> 
    <!-- other methods use the default transaction settings --> 
    <tx:method name="*"/>
  </tx:attributes> 
</tx:advice>

Transaction Propagation: see http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/transaction/annotation/Propagation.html

eg

@Transactional(propagation=Propagation.REQUIRED)

  • REQUIRED – if no tx in progress oen is started. If in progress, tx is joined (THIS IS THE DEFAULT)
  • REQUIRES_NEW – new tx is started whether or not one already active. if previous tx active, it is suspended and new transaction started. if new transaction fails it does not have any impact on prior suspended tx
  • SUPPORTS – if tx active it’s used, it no transaction continues without a tx
  • NOT_SUPPORTED – no tx supported. if tx active, tx is suspended, code completes without tx. On completion returns to caller and previous tx is resumed
  • MANDATORY – tx must be active, and is joined when code called. if no tx active when code is called an exception is thrown
  • NESTED – if tx active, a new child transaction is created. if nested/child transaction fails, this forces parent transaction to also fail. if no tx active, creates a new one (no equivalent in EE?)
  • NEVER – rarely used. opposite of MANDATORY. if no tx active, continue. if tx active, throw exception

Rolling back a transaction

  • RuntimeExceptions always cause a transaction to rollback if not caught and consumed/handled
  • Exception to this is if default behavior is changed by using @Transactional(rollbackFor=ExceptionName.class) to indicate which specific exceptions will cause a rollback

Using @Transactional with JUnits

  • by default, an @Transactional @Test will always rollback db changes on test method completion to leave db intact/unchanged

Spring AOP

Solves problem of cross cutting concerns, like:

  • logging & tracing
  • transaction management
  • security
  • caching
  • error handling
  • performance metrics instrumentation

Goals of Spring AOP:

  • avoid mixing of unrelated concerns in the same code (‘tangling‘ – e.g. business logic and security code)
  • avoid duplication of same/boilerplate code throughout many locations (‘scattering‘, e.g. transaction management)

Spring AOP only works with Spring Beans – cannot be used for Java Classes not managed by Spring (unlike AspectJ)

Pointcut expression matching syntax:

  • designator(return_type package.classname.methodname(params))

designator: e.g. execute – match when method called

return_type: *=wildcard, void, or specific type

package and classname can use * anywhere in the pattern as a wildcard:

  • package and classname are optional and can be omitted, eg perform(*) would match perform method on any class in any package
  • packageA.*.packageC : one wildcard package name between packageA and packageC
  • packageA..packageC: any number of packages
  • classname+ : + indicates any subclass of this class type, eg execution(* *..SomeRepository+.*(*)) – matches any implementation (+) of SomeRepository in any package (*..), and any method with any parameters

methodname can also use wildcard

params

  • ‘..’ indicates any parameters
  • methodname(int, ..) : indicates one int param followed by any other params

Using Annotations to declare an Aspect

@Aspect
public class LoggerAspect
{
    @Before(execution(* *ServiceImpl.*(*))
    public void logMethodCall()
    {
    ....
    }

}

– this pointcut declares an aspect for any method with any params on any class with name ending *ServiceImpl

Equivalent Bean configuration:

<context:component-scan base-package="example"/>
<aop:aspectj-autoproxy/>

<aop:config>
    <aop:aspect ref="loggerAspect">
        <aop:before pointcut="execution(* *ServiceImpl.*(*)" method="logMethodCall"/>
    </aop:aspect>
</aop:config>

<bean id="loggerAspect" class="example.LoggerAspect"/>

Getting Context on matching join points

  • Use JoinPoint as param on Advice impl method
  • Allows access to matching method signature (eg package, name, params)

Advice Types:

@Before

  • before call is made to matching method

@AfterReturning

  • on return from call to matching method

@AfterThrowing

  • matches if target throws an exception
  • Can rethrow as a new exception, but if you do, wrap the original exception so the original context from the exception is preserved

@Around

  • executes before and after method call
  • allows you to either continue with the about-to-be-called method or skip the call ( proceed() )

Methods that call other public methods that are ‘under advice’ in the same class do not get matched with the pointcut. For example, if Class A has methods a1() and a2(), and if the pointcut pattern matches both a1() and a2(), if a1() calls a2() internally, a1() will get the advice, but a2() will not. (KH TODO: would be a nice example to demonstrate this, and the following part too)

If two methods ‘under advice’ are in different classes, and one calls the other, then both methods will get the advice.

Using Android Library Projects in Eclipse

To make other source projects available as dependencies to other projects, open Properties for the project you want to make available. On Android properties, check ‘is Library’ – this makes the project available as a Library project.

In other projects that are dependent on your Library project, on the same Android properties page, press the Add button in the Library section – you’ll see your Library projects listed. Select the one’s that you are dependent on, then Ok.

You don’t need to add any other Project References for compile or runtime time dependencies, this is all taken care of with the Android Library setting.

Core Spring Framework concepts

General:

  • bean creation and dependencies managed by Spring container
  • dependency configuration externalized to context config xml (or via annotations)
  • promotes ‘coding to interfaces’ – best practice to gain flexibility/maintainability
  • promotes loose coupling between classes
  • ability to change implementation classes via config, with no or little required code changes
  • Unit tests easily supported, since no Spring api dependencies in bean classes. DI can be used to inject mocks to support unit testing

The core features of Spring (the ‘Spring Triangle’): POJO/Simple objects are enhanced by the Spring framework by providing:

  • Dependency Injection (DI)
  • Aspect Oriented Programming (AOP)
  • Enterprise Service Abstractions

Bean defs

<bean id="..." class="..."/>
  • id is optional, but must be unique if used
  • name attribute can alternatively be used if you need to define multiple names (comma separated) for the same bean

Setter injection

<bean id="beanA" class="mypackage.ClassA"/>
<bean id="beanB" class="mypackage.ClassB">
    <property name="beanA" ref="beanA"/>
</bean>

Constructor injection

<bean id="beanA" class="mypackage.ClassA"/>
<bean id="beanB" class="mypackage.ClassB">
    <constructor-arg ref="beanA"/>
</bean>

Bean id is OPTIONAL (beans can be retrieved by type). Class is required.

<constructor-arg> can also pass literal values for constructor arguments, eg:

<constructor-arg value="abc"/>
<constructor-arg value="1"/>

Data type conversion on the arg values is implicit. Primitive types, Strings and Collections are supported. Can also support custom types by using a PropertyEditor.

Order of arg values in xml does NOT specify order of values to order of constructor args – Spring will attempt to match using a best guess based on types. e.g. if constructor has args (int, String) and you pass (String, int) as the constructor-args, it will be able to assign them correctly based on type. To remove ambiguity, specify an index to map to intended params:

    <constructor-arg value="1" index="0"/>
    <constructor-arg value="abc" index="1"/>

Can also specify by constructor arg name (in 3.1?) – name=”argument-name”

 

Constructor injection vs Setter injection

  • Using constructor injection enforces mandatory dependencies
  • Setter injection allow for optional dependencies and default values
  • follow standard Java design guidelines
  • if working with existing code, go with the approach that works
  • be consistent with your approach

Support for Collections

    • can inject collections, eg
<property name="names">
  <list>
    <ref bean="name1">
    <ref bean="name2">
    <ref bean="name3">
  </list>
</property>

List of values:

<property name="someListOfValues">
  <list>
    <value>example1</value>
    <value>example2</value>
  </list>
</property>

Factory Beans and Factory Methods

Using a factory bean to produce bean instances:

  • use factory-bean to define name of bean that produces bean instances, and factory-method to define what method to call to create instances
  • beans implementing FactoryBean interface are autodetected by Spring as being available to be used as factory beans
  • dependencies injected using a FactoryBean get their getObject() factory method called automatically… giving a simpler approach to implementing factories using a consistent api

<bean id=”example” class=”com.example.ExampleSingleton” factory-method=”getInstance”/>

– factory-method method must be static

Using a POJO as a FactoryBean:

public class ExampleFactory 
{ 
    public Example getInstance() { ... }
} 

<bean id="factory" class="example.FactoryBean"/> 
<bean id="example" factory-bean="factory" factory-method="getInstance"/>

Initializing app context for standalone app:

ApplicationContext context =
 new ClassPathXmlApplicationContext(new String[] {"application-context.xml"});

Initializing context from multiple config files:

ApplicationContext context =
 new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});

Easy declarative transaction support – use of @Transactional

  • calling methods annotated with @Transaction are intercepted by Spring Framework – a transactional proxy is used to wrap your target class/method with transactional behavior

Bean Lifecycle

3 distinct phases:

  • Initialization: bean definitions are parsed, beans are instantiated and configured, DI performed, beans ready for use
  • Use: beans used by clients
  • Destruction: destruction callbacks invoked, beans destroyed, container shutdown

Initialization

  1. Bean config files loaded and parsed
  2. BeanFactoryPostProcessors executed
  3. For each bean:
    • Instantiate
    • Perform Dependency Injections
    • BeanPostProcessors executed
  4. Beans ready for use

 

During initialization there are two extension points for modifying beans:

  • BeanFactoryPostProcessors: all changes to the definitions of beans BEFORE they are created (example is the PropertyPlaceholderConfigurer which replaces ${} property placeholders in bean configs prior to beans being created). Occurs after bean files are parsed, but before beans are instantiated
  • BeanPostProcesors: perform changes to bean instances, for example to perform initialization logic. Occur AFTER instantiation and Dependency Injection. Usage: @PostContruct annotation, or init-method attribute in XML.

Bean Post Processors

Enabling @PostConstruct Annotations (and others)

<context:annotation-config/>
  • can be performed using JSR250 @PostConstruct annotation or init-method attribute on bean xml def
  • @PostConstruct and init-method are ONLY invoked after all DI has completed
  • @PostContruct is functionally equivalent to bean init-method attribute on bean def
  • this is the only point when beans know all DI has completed
  • if both defined, only init-method is executed since xml config always overrides annotations
  • Example BeanPostProcessors: @Required annotation (RequiredAnnotationBeanPostProcessor)

 

Destruction Phase

  • @PreDestroy annotation
  • destroy-method attribute in XML
  • implement DisposableBean interface (pre Spring 2.5)

Bean Inheritance

  • allows common bean config, eg properties, to be inherited
  • abstract=”true” : defines the base bean. Abstract/base beans are NOT instantiated
  • parent=”parent_bean_name” defines the parent that this bean inherits from
  • beans inheriting from a parent can change property values
  • any class not declared abstract=”true” can also be used as a parent
  • both parent and child classes are instantiated
  • child classes can override inherited properties and even the class

Importing Config Files

&ltimport resource="path/to/context.xml";/&gt;

Can use resource prefixes: classpath

Using the p namespace

Used as a shorthand or setting properties.

Add namespace definition:

xmlns:p="http://www.springframework.org/schema/p"

For this example:

<bean id="beanA" class="mypackage.ClassA"/>
<bean id="beanB" class="mypackage.ClassB">
    <property name="beanA" ref="beanA"/>
</bean>

You can now condense down to:

<bean id="beanA"/>
<bean id="beanB" p:beanA-ref="beanA"/>
</bean>

Property values: p:propertyname=”value”

Using the util namespace

Create a bean as a Set of Enum values from an Enum:

<util:set id=”fruit” value-type=”some.example.Fruit”>
<value>APPLE</value>
<value>PEAR</value>
</util:set>

XML configuration versus Annotations

  • XML always overrides Annotations

 

Bean Scopes

  • singleton – default scope – only single instance of bean created
  • prototype – creates new instance when bean requested
  • session – web specific – instance per user session
  • request – web specific – instance per user request
  • custom – user configurable

 

Spring Tool Suite (STS) / Eclipse bean support features

  • In project Properties, Spring / Beans Support – add list of app context files in use to enable autocomplete/validation features.
  • Group related app context files as ‘Config Sets’ to view consolidated view of bean configs and dependencies
  • From Spring Explorer view, right click Config Set and ‘Open Dependency Graph’ to see graphical view of all beans from all app context files in a Config Set