I'm developing a big web application that uses JSF and hibernate as its ORM. My hibernate sessions are long (the user can do big amount of modifications on the screen and the changes will only be persistent on DB when he'll press the save button) I'm recently struggling with an issue of roll-back / cancellation of user modification and looking for different solutions and approaches.
I want to recover from a violation constraint exception ("ORA-02292: integrity constraint").
Consider the following scenario:
there is a table 'X' with a record 'x' and a table 'Y' with a record 'y' - where 'x' Depends on 'y' by a foreign key.
The user is trying to delete record 'y' and although there is a future possible integrity constraint violation on this step,
I'm not throwing any exception because the user is able to fix it later and only if he won't fix it and try to save the screen the DB will throw an exception which will be aggregated to the user interface.
I can't find a good way to recover from this violation.
In the save process, after trying to delete record 'y', DB launches the "ORA-02292: integrity constraint" exception as expected.
My problem is that if such an error occurred and the user did fixed the foreign key constraint by selecting another record instead of 'y', hibernate won't recognize it because AFAIK it will still first try to remove 'y' (because of the action queue) and fail before it comes to the action that replaces 'y' with another entity.
So what's going on is that the DB keeps firing exceptions while trying to save changes and I can't find a way to fix it without refreshing the entire screen (which means that the new hibernate session loosing all of the user new data).
it seems like the action queue saves the delete action and won't clear it even if Session "evict" or "clear" methods are called.
I am aware that I could validate changes before committing them and that it might work but I'm not interested in this kind of solution because: 1. validate a large amount of possible changes can cause a performance issue, furthermore I believe that oracle DB can do it for me much better. 2. I don't want to enforce the user to a specific order of actions.
UPDATE:
I feel that I should shed some light on the application requirements:
The application was built in a way that committing changes to DB can only occur at the save phase - This is a user demand and unfortunately it's not open for discussion,
The idea behind it is that the user wants to make changes without a specific kind of order and fix wrong set of data whenever he wants to before pressing the save button.
As a result of this requirement, validation is also preferred to take place in the save phase.
I am aware of the possibility of validating each one of the user modification right away as Dragan Bozanovic pointed out bellow, but as I said this is not the preferred way by the user.
So, as I see it I can solve the problem in three different ways:
1.
Validate all modifications in the save phase - as I said it can be a performance issue because there can be many validations to make.
2. Validate each user modification right away - again this is not the preferred option by the user but will do if must.
3. Find a way of handling such scenarios (of integrity constraint...) in the DB level - I`ll appreciate more suggestions, if any, to this approach.
You can't, your transaction is already marked for rollback, it would fail even without a repeated deletion.
The solution is to validate the data/actions before you execute them in the DB.
But you said that you don't want it.
"validate a large amount of possible changes can cause a performance issue" But not validating them can cause inconsistent and wrong saved state (if you have validation constraints that are difficult/impossible to implement in database).
"oracle DB can do it for me much better" I disagree. Other than foreign key, not null and a few other constraints, Java based validation is much more flexible and powerful.
"I don't want to enforce the user to a specific order of actions." But you want to allow them to delete something that should not be deleted and then raise an error 10 minutes later when they try to save their cumulative changes which may be dependent on each other (and assume that the deletion will be successful). I am sure that the user will appreciate to get the error right after they try to perform deletion, in order not to loose 10 minutes more in vain.
My point and suggestion is you should do a validation before you instruct Hibernate to delete the entity.