Question

Consider the following code snippet. (I am using Spring 3.1 and Hibernate 3.6)

@Override
@Transactional
public <T extends Termination> void progressToPendingStage(Class<T> entity,
        Long terminationId, String userName) throws Exception {

    Termination termination = findTerminationById(entity, terminationId);
    //TODO improvise such that email does not get sent if data is not saved
    if (termination.getStatus().equals(TerminationStatus.BEING_PREPARED.toString())) {
        termination.setStatus(TerminationStatus.PENDING.toString());
        termination.setSubmittedDate(new Date());
        termination.setSubmittedBy(userName);
        saveOrUpdateTermination(termination);
        //Send an email to SAS
        emailHelper.configureEmailAndSend(termination);
    }   

}

Unit tests for the above method indicate that email will be sent regardless that the saveOrUpdateTermination(termination) throws an exception or not. On further testing and some research I have uncovered that this behavior is the expected behavior. This is not what the business rules desire. An email should be sent only if the termination record was saved successfully. Any suggestions on how to make this behave in the desired manner? One way I can think of is to make the caller handle the exception thrown by the progressToPendingStage method and if no exception was thrown send an email. Am I on the right track or can we alter the way @Transaction behaves.

Was it helpful?

Solution

I have solved this issue by designing around the problem. Sending an Email was never meant to be part of the transaction. I created an object that performed post saving tasks. The object will catch the exception thrown upon saving the termination and if no exceptions were thrown I would then trigger an email to be sent out. One could also put this in an Spring Aspect which could be executed upon successfully returning after a successful save.

Lessons learn't: Don't include steps that don't belong in a method marked with @transaction. If its included in a transaction Spring will silently handle the exception and not throw the exception till the transaction is finished. In short if a method is annotated with @Transaction every line in that method will be execute even though a line in the middle of the method throws an exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top