May 9th, 2008, 05:09 PM
A bug in StatefulRetryStepFactory?
After reading the documentation for the "StatefulRetryStepFactoryBean", I was under the impression that by using that step it would retry failed items as long as:
1) the number of retries did not exceed the "retryLimit" and
2) the thrown exceptions were an instance of "retryableExceptionClasses"
However, as long as the retry limit is set to a value greater than 0, it appears this class will always retry. For instance, using the test class "StatefulRetryStepFactoryBeanTests" and modifying the ItemReader to unconditionally throw an Exception causes the test to infinitely loop and never complete.
Am I misunderstanding how this class is used? Thanks for your help!
May 9th, 2008, 05:27 PM
If you are in an infinite loop, you probably are still using 1.0.0, right? 1.0.1 will exit the loop with an error that tries to explain what probably went wrong. Read the documentation section on ItemKeyGenerator in relation to the stateful retry, and see if it applies to your case.
You might be the exception, but 9 times out of 10 if your symptoms are presented it turns out that the key generation strategy is faulty and/or the items do not have a stable identity.
May 12th, 2008, 06:40 PM
Using release 1.0.1, I can still trigger the infinite loop by doing two things in the test class:
1) Make the writer unconditionally throw an exception.
2) Comment out the the "setSkipLimit()" call.
With this situation, I would expect the class to retry after 10 iterations (the retry limit). Is that the wrong expectation? Thanks for your help!
May 12th, 2008, 09:05 PM
What Dave is saying is that there is likely an issue with your items and how they are identified. Have you overriden equals so that it will be garunteed to be unique even if the item is regenerated by the reader? (which it generally will be in a rollback scenario) If not, that's probably the issue.
May 12th, 2008, 09:12 PM
Well, I recreated the infinite loop using your own JUnit test. And unless I'm misunderstanding, I don't think that configuration should act in that way - it's not a strange configuration and one I would expect the framework to handle.
With my own item reader I'm using the stock HibernateCursorItemReader, but the issue is that I want to handle the Writer possibly throwing an exception.
May 12th, 2008, 11:28 PM
Right, how you created the loop is irrelevant. The real issue is how your items are identified. The framework uses object comparison to determine if it is seeing the same item that should be retried. In the case of a write failure, the whole chunk is rolled back, and the ItemReader is 'reset'. The items are then recreated. If your domain objects don't override equals, then the comparison will fail, because the default behaviour for Object equals uses the memory location. Unless the reader buffers items itself, there's no way around this (the HibernateCursorItemReader doesn't)