Use Spring JdbcTemplate if you don't want to access your database schema via a domain model. Using JdbcTemplate you are using a lower level access, with more flexibility, but probably also more boilerplate.
Spring JdbcTemplate can be more easily used with exotic database schemas and a stored procedure focus. Using JPA you need to make sure that database schema maps correctly to the domain model.
Both technologies need developers knowing relational databases, SQL and transactions. With JPA you get more hidden complexity though.
JPA is to my knowledge more easily pluggable to data caching layers, since the object oriented focus makes cache entry identification, update and invalidation easier.
You can fine tune JdbcTemplate based backends better, but there is for most cases more code involved.
Some other aspect to consider is that although with JPA you get a domain model for your database schema you will often need to use additional DTO classes. Using JdbcTemplate you can directly operate with DTO classes.
I agree with @Timo. The only other insight I would add/expand upon is that ORM has different semantics from pure sql access to your data.
The point of ORM is to abstract away the fact that your data is in a DB at all, as much as possible. When you use ORM properly, all persistence operations are dealt with in one (hopefully) thin layer. Your model objects will have little to no persistence code; the fact that you are using ORM should be invisible to your model.
Because of this, ORM is very good at making your life easy for certain types of operations, namely simple CRUD operations. You can load your model objects, present them, update them, delete them quite easily. It makes your life easier because when you access your data, you get model objects back, on which you can write business logic. If you use JDBC, you will have to 'hydrate' your object instances from the data, which can be complicated and error-prone.
ORM is not always the best choice. JPA is a tool for a job, if the tool is not sufficient for the job you will want to find a better tool. For example, I had a scenario where I had to copy an entire object graph and save a new copy of those objects. If I had used ORM (like I tried to do), I had to load all the objects out of the DB, then copy them, then save the new objects. I took way too long.
The better solution was simply to use jdbc based operations and 'insert via select' sql calls to create the new rows. It was fast, the code was simpler.
The other thing to consider is that you are comfortable with JDBC, and have deadlines, you don't have to jump on the ORM bandwagon. The Spring JdbcTemplate classes are extremely powerful and helpful. Sometimes the best tool for the job is the one you know. You should familiarize yourself with ORM, but not necessarily for a project with high expectations. There is a lot to learn and its not trivial -- really you are trading one set of complexities with another in the choice to use jdbc vs orm.
I'm a bit late to this post, but I tend to use JdbcTemplate over ORM. I know SQL (pretty well) and really don't want to be "abstracted" away from my DB. I find most of the time, my apps are using DB views where I push most business logic up to. I have properly layered DAOs that have JdbcTemplate implementations. It feels "clean" and most boilerplate code is hidden by JdbcTemplate (and it's online documentation seems MUCH better then ORM stuff). The limited time I've used something like Hibernate, I found when it worked, it save me some time...but when it wasn't working properly, it cost me days of "WTF" debugging. I've never had to spend more then 20 minutes debugging JdbcTemplate DAO impls. I think the key, as others noted, is how comfortable you are with SQL / Schema Design
It is not mentioned in the other answers but it is fine to use both. In my App I use JPA and JdbcTemplate, for crud type operations I use JPA but for reporting or where it is easier I use jdbcTemplate.
@Repository
public class FooRepository
{
@PersistenceContext
private EntityManager entityManager;
@Autowired(required = true)
private JdbcTemplate jdbcTemplate;
public void saveFoo(Foo foo)
{
this.entityManager.persist(foo);
}
public List<SomeReportPojo> getSomeReport()
{
return this.jdbcTemplate.queryForList("SELECT .. ",SomeProjectPojo.class);
}
}
The great thing about Spring is that the exception translation from JPA exceptions to spring Dao exception hierarchy works with both JPA and jdbcTemplate. So use JPA when it makes sense and jdbcTemplate when it makes sense.
At work we use Hibernate JDBCTemplate because it has more flexibility. It also has better performance than JPA because you are not "loading" a lot of unnecessary data into your app.
In the JDBCTemplate case, your SQL skills go a long way in giving you exactly what you need at the right speed.