PDA

View Full Version : Mapping a custom error code to OptimisticLockingFailureException.



mdownes
10-26-2007, 03:20 PM
We are performing data access as follows:

We are using SQL Server with stored procedures for all data access.
It is the responsibility of the stored procedure to perform the optimistic locking check.
If there is an optimistic locking failure (i.e. the object is out of date), the stored procedure returns an error code (50001).


How do I best set-up handling for the error code?

I do not want to change the existing error code handling provided by ErrorCodeExceptionTranslator and I still want the handling provided by the FallbackExceptionTranslator.

I have implemented my own IAdoExceptionTranslator (OptimisticLockingFailureExceptionTranslator) which mimics the FallbackExceptionTranslator with the addition of handling the error code and throwing an OptimisticLockingFailureException.

This works fine. However, I am unsure how to register it. I have registered it as a fallback translator programmatically within my StoredProcedure object:


OptimisticLockingFailureExceptionTranslator myTranslator = new OptimisticLockingFailureExceptionTranslator();
myTranslator.DbProvider = dbProvider;
this.AdoTemplate.ExceptionTranslator = myTranslator;


I could do this in every StoredProcedure object but ideally, I want to override the default behaviour for AdoTemplate. Also, this has only registered it as ExceptionTranslator. I really need to register it as the fallbackTranslator on the ErrorCodeExceptionTranslator. How do I do this?

Mark Pollack
10-30-2007, 01:24 PM
Hi,

I've improved ErrorCodeExceptionTranslator in response to your post to be more subclass friendly for your scenario. There is now a protected method, TranslateException, with the signature below



protected virtual DataAccessException TranslateException(string task, string sql, string errorCode, Exception exception)



That will be called before Spring tried to perform translation based on error codes and failing that, the FallbackExceptionTranslator. Depending on where in the translation chain you would like to insert your own translation code you can either override the previous method or configure ErrorCodeExceptionTranslator's FallbackTranslator property. If you can upgrade to use this new method, I'd go that route, otherwise what you did works well because your error code is likely not to overlap with any of the existing ones.

In terms of having to register the exception translator programmatically over and over again, it is typical to use dependency injection to configure a single instance of AdoTemplate that is then shared throughout all the object in your data access layer. In your current case that would look something like this...


<object id="adoTemplate type="...AdoTemplate">
<property name="ExceptionTranslator" ref="exceptionTranslator"/>
</object>
<object id="exceptionTranslator type="...errorCodeExceptionTranslator">
<property name="FallbackTranslator ref="optimisticLockingFailureExceptionTranslator/<
</object>
<object id="optimisticLockingFailureExceptionTranslator" type="..OptimisticLockingFailureExceptionTranslator"/>


and your data access layer object, say inheriting from AdoDaoSupport, would then be


<object id="accountRepository" type="...AccountRepository">
<property name="AdoTemplate" ref="adoTemplate"/>
</object>


Cheers,
Mark

Mark Pollack
10-30-2007, 03:11 PM
Hi,

I took a look at the Java code base and there is another point of extensibility via configuration that would cover your use case, that is the configuration of the ErrorCodeExceptionTranslator's ErrorCodes property which in turn as a CustomErrorCodesTranslation property. I've made a JIRA issue (http://opensource.atlassian.com/projects/spring/browse/SPRNET-757) for this.

Cheers,
Mark