Notes on Sprint Frameworks



Where to go to download JARs

Go to http://www.springsource.org/download

There, you'll find something like "GET THE LATEST SPRING RELEASES HERE". Choose the latest one unless you know better. Click "Download". This gets you down a big zip containing loads of JARs with names like:

org.springframework.aop-3.1.0.RC2.jar
org.springframework.asm-3.1.0.RC2.jar
org.springframework.aspects-3.1.0.RC2.jar
org.springframework.beans-3.1.0.RC2.jar
org.springframework.context-3.1.0.RC2.jar
org.springframework.context.support-3.1.0.RC2.jar
org.springframework.core-3.1.0.RC2.jar
org.springframework.expression-3.1.0.RC2.jar
org.springframework.instrument-3.1.0.RC2.jar
org.springframework.instrument.tomcat-3.1.0.RC2.jar
org.springframework.jdbc-3.1.0.RC2.jar
org.springframework.jms-3.1.0.RC2.jar
org.springframework.orm-3.1.0.RC2.jar
org.springframework.oxm-3.1.0.RC2.jar
org.springframework.spring-library-3.1.0.RC2.libd
org.springframework.test-3.1.0.RC2.jar
org.springframework.transaction-3.1.0.RC2.jar
org.springframework.web-3.1.0.RC2.jar
org.springframework.web.portlet-3.1.0.RC2.jar
org.springframework.web.servlet-3.1.0.RC2.jar
org.springframework.web.struts-3.1.0.RC2.jar

Depending on what you're doing, you'll need one or more of these.



Where is stuff?

It's challenging to find stuff. For example, @Repository is in org.springframework.context-3.1.0.RC2.jar while @Transactional is in org.springframework.transaction-3.1.0.RC2.jar.

Look for sample code. The Spring documentation will prat on and on using annotations without telling you where to get them. Sample code, on the other hand, will probably contain import statements that reveal, for instance, that @Repository is in org.springframework.stereotype.Repository.

Then, you can Google for "org.springframework.stereotype jar" and find out where it is (in Spring "context"; see first section above, this would be in org.springframeword.context-3.1.0.RC2.jar).



Annotations

These are annotations, not all necessarily from Spring, but ones that I'm using in work primarily motivated by moving to adopt a subset of Spring framework.



Secret sauce for Hibernate templates

There's some secret thing that has, so far, defied my understanding, but which works for setting up DAOs (or here, I'm calling it a "repository" since that's what my work colleagues are liking).

Go looking for method getHibernateTemplate() in Spring or Hibernate JARs and you won't really find it. It's something that gets created when you extend HibernateDaoSupport in a special way. And the consuming class can't extend it directly either.

If you wish to use Hibernate templates to avoid having to inject a SessionFactory by hand, you must set up a helper class (abstract) thus:

package com.acme.user.entity;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * With annotations in use, it's not possible to extend HibernateDaoSupport directly
 * in the DAO (Repository) class, hence this work-around, a custom class that does it
 * that's auto-wired to the session factory.
 */
public abstract class CustomHibernateDaoSupport extends HibernateDaoSupport
{
    @Autowired
    public void anyMethodName( SessionFactory sessionFactory )
    {
        setSessionFactory( sessionFactory );
    }
}

Then, the DAO class can be implemented thus:

package com.acme.user.entity;

import java.util.List;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * This is the repository or data-access object that isolates CRUD from the rest of the application
 * code, using Hibernate templating (and not Hibernate Criteria).
 */
@Repository
public class AccountRepository extends CustomHibernateDaoSupport
{
    @Transactional( readOnly = false, propagation = Propagation.MANDATORY )
    public void create( Account account )
    {
        getHibernateTemplate().save( account );
    }

    @Transactional( readOnly = true, propagation = Propagation.MANDATORY )
    public Account findByPhone( String phone )
    {
        List< ? > list = ( List< ? > ) getHibernateTemplate().find( "from Account where phone=?", phone );
        return ( Account ) list.get( 0 );
    }

    @Transactional( readOnly = true, propagation = Propagation.MANDATORY )
    public Account findByName( String name )
    {
        List< ? > list = ( List< ? > ) getHibernateTemplate().find( "from Account where name=?", name );
        return ( Account ) list.get( 0 );
    }

    @Transactional( readOnly = false, propagation = Propagation.MANDATORY )
    public void update( Account account )
    {
        getHibernateTemplate().update( account );
    }

    @Transactional( readOnly = false, propagation = Propagation.MANDATORY )
    public void delete( Account account )
    {
        getHibernateTemplate().delete( account );
    }
}

If you don't do it this way, likely you'll find getHibernateTemplate() gone missing and you won't find it in an JAR. Also, to link this code, you'll need something like org.springframework.core-3.1.0.RC2.jar in order to satisfy NestedRuntimeException.