[SPRNET-1391] ExceptionTranslation doesnt work for SQLite Created: 26/Nov/10  Updated: 16/May/11  Resolved: 16/May/11

Status: Resolved
Project: Spring.NET
Component/s: Spring-NET-DA
Affects Version/s: 1.3.0
Fix Version/s: 1.3.2

Type: Bug Priority: Minor
Reporter: Tobi Tobsen Assignee: Mark Pollack
Resolution: Complete Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Spring.net 1.3
.Net 3.5 Sp1

Attachments: Zip Archive ExceptionTranslationTest.zip    


I attached a failing unit test showing my intentions.

I think it is related to the embedded resource Spring.Data.Common.dbproviders.xml:
<constructor-arg name="errorCodeExceptionExpression" value="Number.ToString()"/>

"Number" isn't a property of System.Data.SQLite.SQLiteException. The correct property might be "ErrorCode" of the Enum-Type "SQLiteErrorCode".

I tried the following things without success:

  • I added a custom dbProviders.xml "the crude way" (as described here http://www.springframework.net/doc-latest/reference/html/dbprovider.html#dbprovider-dbprovider)
    but since the SessionFactoryUtils' NewAdoExceptionTranslator(...) looks for the first matching DbProvider (GetDbProvider(..)) and the additionally added DbProvider is the last one in the providerNames[] (line 666, SessionFactoryUtils.cs), still the DbProvider with a ErrorCodeExceptionTranslator using the wrong errorCodeExceptionExpression will be returned.

Also the "errorCodeExceptionExpression" is only available as a constructor argument, not as a property, so property overwriting of errorCodeExceptionExpression via Spring.Objects.Factory.Config.PropertyOverrideConfigurer is not possible either.

  • I then declared the Spring.Data.Support.ErrorCodeExceptionTranslator explicitly using the a DbProvider (with "ErrorCode" instead of "Number" as the errorCodeExceptionExpression) and inject it into the LocalSessionFactoryObject instance so the localSessionFactoryObject doesn't have to call SessionFactoryUtils.NewAdoExceptionTranslator(sessionFactory) which would return a new AdoExceptionTranslatort the wrong DbProvider instance.
    Still the exception won't be translated properly.

I was able to reduce the necessary steps and debug the attached unittest. It seems that the SQLiteErrorCode-Enumeration's ToString representation (e.g. "Busy") is used instead of the integer value casted to string (e.g. "5").
A suitable errorCodeExceptionExpression could be "((int)ErrorCode).ToString()" but this isn't parseable by spring.
Maybe the ExtractErrorCode(...) of the ErrorCodeExceptionTranslator has to handle it differently (line 167, LocalSessionFactoryObject.cs) and has to use the string represnetation of the enums integer value instead of the string representation of the Enumeration.

Maybe there is already a built in solution I haven't found?

Comment by Mark Pollack [ 16/May/11 ]

<constructor-arg name="errorCodeExceptionExpression" value="ErrorCode.ToString('D')"/> works. Will update as appropriate for new version of the driver as well.

Comment by Mark Pollack [ 16/May/11 ]

thanks for the test case!

Generated at Sat Jul 11 06:01:39 UTC 2020 using Jira 8.5.4#805004-sha1:0444eab799707f9ad7b248d69f858774aadfd250.