Search This Blog

Sunday 26 August 2012

Spring and Database - the cool stuff

Spring gives us some real cool advantages when integrating with databases. Theses advantages are applicable whether you connect to the database via JDBC or via frameworks.
Spring Data Exception mechanism:
When I first wrote my JDBC code in college, I came across the (in) famous SQLException. I added the catch block and then wondered what do do inside it. I mean if my db did not work, what graceful action was I to take ? My user could do zilch with an application where there was a query error or an unset db connection. The point was, SQLExceptions if any occurred and were handled during development. So what were these catch blocks doing in the code?
Also if there are some exceptions that can occur at run time and can be handled, it would mean that the code has to dig inside the SQLException to see if it can do anything. Hibernate developers had this in mind when they developed their framework. So they created their own exception hierarchy with different exceptions for different failure scenarios. So a user could actually deal with those exceptions that can be handled at run time and provide some graceful error handling to the user. But what of the other exceptions? How do we escape those empty catch blocks? The framework guys did the next cool thing. In Hibernate 3, they made the exceptions run time exceptions. It now meant "Handle if you can, else forget it." No more dumb catch blocks.
Spring has gone ahead and generalized this behaviour. So when working with Spring we have
  • a hierarchy of data access exceptions 
  • each exception is descriptive and for a specific scenario
  • all are run time and need to be only handled if they can be.
  • they are not directly associated with a specific persistence framework and therefore can be used with JDBC/Hibernate/JDO/Ibatis or some other framework
 This is a list of exceptions I picked up from Springs docs:
Exception Detail
DataAccessException Root of the hierarchy of data access exceptions
CannotAcquireLock
Exception
Thrown on failure to acquire a lock during an update, for example during a "select for update" statement.
CannotSerialize
TransactionException
Thrown on failure to complete a transaction in serialized mode due to update conflicts.
CleanupFailureData
AccessException
Thrown when Spring couldn't cleanup after a data access operation, but the actual operation went OK.
ConcurrencyFailure
Exception
Thrown on concurrency failure.
DataAccessResource
FailureException
Thrown when a resource fails completely: for example, unable to connect to a database using JDBC.
DataIntegrity
ViolationException
Thrown when an attempt to insert or update data results in violation of an integrity constraint.
DataRetrievalFailure
Exception
Thrown if certain expected data could not be retrieved, e.g. when looking up specific data via a known identifier. This exception will be thrown either by O/R mapping tools or by DAO implementations.
DeadlockLoserData
AccessException
Generic exception thrown when the current process was a deadlock loser, and its transaction rolled back.
DuplicateKeyException thrown when an attempt to insert or update data results in violation of an primary key or unique constraint.
EmptyResultData
AccessException
thrown when a result was expected to have at least one row (or element) but zero rows (or elements) were actually returned.
IncorrectResultSize
DataAccessException
thrown when a result was not of the expected size, for example when expecting a single row but getting 0 or more than 1 rows.
IncorrectUpdateSemantics
DataAccessException
thrown when something unintended appears to have happened with an update, but the transaction hasn't already been rolled back.
InvalidDataAccess
ApiUsageException
thrown on incorrect usage of the API, such as failing to "compile" a query object that needed compilation before execution.
InvalidDataAccess
ResourceUsageException
thrown when we use a data access resource incorrectly.
NonTransient
DataAccessException
Root of the hierarchy of data access exceptions that are considered non-transient - where a retry of the same operation would fail unless the cause of the Exception is corrected.
NonTransient
DataAccess
ResourceException
thrown when a resource fails completely and the failure is permanent.
OptimisticLocking
FailureException
thrown on an optimistic locking violation.
PermissionDenied
DataAccessException
thrown when the underlying resource denied a permission to access a specific element, such as a specific database table.
PessimisticLocking
FailureException
thrown on a pessimistic locking violation.
RecoverableData
AccessException
thrown when a previously failed operation might be able to succeed if the application performs some recovery steps and retries the entire transaction or in the case of a distributed transaction, the transaction branch.
TransientData
AccessException
Root of the hierarchy of data access exceptions that are considered transient - where a previously failed operation might be able to succeed when the operation is retried without any intervention by application-level functionality.
TransientDataAccess
ResourceException
thrown when a resource fails temporarily and the operation can be retried.
TypeMismatch
DataAccessException
thrown on mismatch between Java type and database type: for example on an attempt to set an object of the wrong type in an RDBMS column.
UncategorizedData
AccessException
Normal superclass when we can't distinguish anything more specific than "something went wrong with the underlying resource": for example, a SQLException from JDBC we can't pinpoint more precisely.
I highlighted those that I found interesting.

No comments:

Post a Comment