Spring Top – Temp

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

Lightrun – Third Party Code

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Overview

In this quick tutorial, we will go through the most important types of the common NonTransientDataAccessException and illustrate them with examples.

2. The Base Exception Class

Subclasses of this main exception class represent data access related exceptions which are considered non-transient or permanent.

Simply put, that means that – until the root cause is fixed – all future attempts of a method that caused an exception, will fail.

3. DataIntegrityViolationException

This subtype of NonTransientDataAccessException is thrown when an attempt to modify data causes a violation of an integrity constraint.

In our example of the Foo class, the name column is defined as not allowing the null value:

@Column(nullable = false)
private String name;

If we attempt to save an instance without setting a value for the name, we can expect a DataIntegrityViolationException to be thrown:

@Test(expected = DataIntegrityViolationException.class)
public void whenSavingNullValue_thenDataIntegrityException() {
    Foo fooEntity = new Foo();

3.1. DuplicateKeyException

One of subclasses of the DataIntegrityViolationException is DuplicateKeyException, which is thrown when there is an attempt to save a record with a primary key that already exists or a value that is already present in a column with a unique constraint, such as attempting to insert two rows in the foo table with the same id of 1:

@Test(expected = DuplicateKeyException.class)
public void whenSavingDuplicateKeyValues_thenDuplicateKeyException() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);
    jdbcTemplate.execute("insert into foo(id,name) values (1,'a')");
    jdbcTemplate.execute("insert into foo(id,name) values (1,'b')");

4. DataRetrievalFailureException

This exception is thrown when a problem during retrieving data appears, such as looking up an object with an identifier which doesn't exist in a database.

For example, we're going to use the JdbcTemplate class which has a method that throws this exception:

@Test(expected = DataRetrievalFailureException.class)
public void whenRetrievingNonExistentValue_thenDataRetrievalException() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);
    jdbcTemplate.queryForObject("select * from foo where id = 3", Integer.class);

4.1. IncorrectResultSetColumnCountException

This exception subclass is thrown when attempting to retrieve multiple columns from a table without creating the proper RowMapper:

@Test(expected = IncorrectResultSetColumnCountException.class)
public void whenRetrievingMultipleColumns_thenIncorrectResultSetColumnCountException() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);

    jdbcTemplate.execute("insert into foo(id,name) values (1,'a')");
    jdbcTemplate.queryForList("select id,name from foo where id=1", Foo.class);

4.2. IncorrectResultSizeDataAccessException

This exception is thrown when a number of retrieved records differs from expected one, for example when expecting a single Integer value, but retrieving two rows for the query:

@Test(expected = IncorrectResultSizeDataAccessException.class)
public void whenRetrievingMultipleValues_thenIncorrectResultSizeException() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);

    jdbcTemplate.execute("insert into foo(name) values ('a')");
    jdbcTemplate.execute("insert into foo(name) values ('a')");

    jdbcTemplate.queryForObject("select id from foo where name='a'", Integer.class);

5. DataSourceLookupFailureException

This exception is thrown when a specified data source cannot be obtained. For the example, we will use the class JndiDataSourceLookup, to look for a nonexistent data source:

@Test(expected = DataSourceLookupFailureException.class)
public void whenLookupNonExistentDataSource_thenDataSourceLookupFailureException() {
    JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
    DataSource dataSource = dsLookup.getDataSource("java:comp/env/jdbc/example_db");

6. InvalidDataAccessResourceUsageException

This exception is thrown when a resource is accessed incorrectly, for example when a user lacks SELECT rights.

In order to test this exception, we'll need to revoke the SELECT right for the user, then run a SELECT query:

@Test(expected = InvalidDataAccessResourceUsageException.class)
public void whenRetrievingDataUserNoSelectRights_thenInvalidResourceUsageException() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);
    jdbcTemplate.execute("revoke select from tutorialuser");

    try {
    } finally {
        jdbcTemplate.execute("grant select to tutorialuser");

Notice that we are restoring the permission on the user in the finally block.

6.1. BadSqlGrammarException

A very common subtype of InvalidDataAccessResourceUsageException is BadSqlGrammarException, which is thrown when attempting to run a query with invalid SQL:

@Test(expected = BadSqlGrammarException.class)
public void whenIncorrectSql_thenBadSqlGrammarException() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);
    jdbcTemplate.queryForObject("select * fro foo where id=3", Integer.class);

Notice of course the fro – which is the invalid aspect of the query.

7. CannotGetJdbcConnectionException

This exception is thrown when a connection attempt through JDBC fails, for example when the database url is incorrect. If we write the url like the following:


Then the CannotGetJdbcConnectionException will be thrown when attempting to execute a statement:

@Test(expected = CannotGetJdbcConnectionException.class)
public void whenJdbcUrlIncorrect_thenCannotGetJdbcConnectionException() {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource);
    jdbcTemplate.execute("select * from foo");

8. Conclusion

In this very to the point tutorial we had a look at some of the most common subtypes of the NonTransientDataAccessException class.

The implementation of all examples can be found in the GitHub project. And of course all examples are using an in-memory database so you can easily run them without setting anything up.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

Generic footer banner
Comments are closed on this article!