-
1. Re: StaleObjectStateException return to same page
coralfe Apr 4, 2008 5:16 PM (in response to coralfe)I've even tried the interceptor mentioned
here
to no avail!! -
2. Re: StaleObjectStateException return to same page
coralfe Apr 7, 2008 3:15 PM (in response to coralfe)For anyone else with this issue:-
Solved it to a satisfactory level by calling
Redirect.instance().captureCurrentView(); in the method that opens the dialog and putting<exception class="javax.persistence.OptimisticLockException"> <redirect view-id="#{redirect.viewId}"> <message>#{messages['error.OptimisticLockException']} </message> </redirect> </exception>
In pages.xml
Wasn't quite the control I was hoping for but at least its usable.
-
3. Re: StaleObjectStateException return to same page
eirirlar Apr 9, 2008 8:51 AM (in response to coralfe)I'm having a similar problem, could you post some code samples?
-
4. Re: StaleObjectStateException return to same page
coralfe Apr 10, 2008 10:34 AM (in response to coralfe)Not much else really...
Method called when open modal:
//manual so we dont get concurrentexception at odd times @Begin(flushMode=FlushModeType.MANUAL) public String prepAlterStrategy(Object whatever) { //so concurrent calls errors end up in same place // and pages.xml redirect.viewId is set // in this place remembers page before modal is opened Redirect.instance().captureCurrentView(); ... return "prepAlter";//faces navigation in modal }
page opening modal:
<rich:menuItem submitMode="ajax" value="edit" action="#{backingBean.prepAlterStrategy(stratBubble)}" reRender="modalContent" oncomplete="javascript:Richfaces.showModalPanel('sm_modal')" />
and the submit button on the modal calls and action with:
object = entityManager.merge(object); entityManager.flush();
Your viewid page also needs a h:messages
Then pages.xml as above.Not sure if this best solution.
-
5. Re: StaleObjectStateException return to same page
eirirlar Apr 10, 2008 12:13 PM (in response to coralfe)How do you handle the corrupt hibernate session? From the book
Java Persistence with Hibernate
:
All exceptions thrown by Hibernate are fatal. This means you have to roll back the database transaction and close the current Session. You arent't allowed to continue working with a Session that threw an exception.I've handled it the following way, which is a bit hacky but working: In a stateful conversational sesssion bean with flushmode.manual, I have a private method called persist() which public methods of the bean calls when they need to flush to the database. The persist method takes care of any potential StaleObjectStateException. It does so by getting another pojo seamcomponent which I've called ConcurrencyResolver. ConcurrencyResolver has a method which is REQUIRES_NEW that replaces the hibernate session that resides in this conversation.
private void persist() { try { vrvaskSession.flush(); } catch (StaleObjectStateException sose) { ConcurrencyResolver concurrencyResolver = (ConcurrencyResolver) Component .getInstance("concurrencyResolver"); hibernateSession = concurrencyResolver.replaceSession("hibernateSession"); object = (ObjectClass) hibernateSession.get(object .getClass(), object.getId()); facesMessages.add(FacesMessage.SEVERITY_WARN, "#{messages.staleObjectStateException}"); } }
@Name("concurrencyResolver") public class ConcurrencyResolver { @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public Session replasceSession(String sessionName) { // Get session wrapper from conversation ManagedHibernateSession currentSession = (ManagedHibernateSession) ScopeType.CONVERSATION .getContext().get(sessionName); // End the transaction so 'sessionWillPassivate' can do it's job UserTransaction transaction = Transaction.instance(); try { if (transaction.isActive()) transaction.rollback(); currentSession.getSession().clear(); // Closes the current session currentSession.sessionWillPassivate(null); // Creates a new session return currentSession.getSession(); } catch (Exception e) { throw new RuntimeException(e); } } }
This solution would be less hacky if Seam had some api support for replacing the current hibernate session, or for optimistic locking exception handling in general.
-
6. Re: StaleObjectStateException return to same page
eirirlar Apr 10, 2008 12:33 PM (in response to coralfe)
vrvaskSession.flush();Should be hibernateSession.flush()
public Session replasceSession(String sessionName) {Should be public Session replaceSession(String sessionName)
-
7. Re: StaleObjectStateException return to same page
christian.bauer Apr 10, 2008 12:41 PM (in response to coralfe)This has been long on the TODO list for Hibernate, sometimes disguised as Savepoints I think. From what I read it is one of the features for Hibernate 3.3.
In the book it's referred to as
Merge Changes
resolution of optimistic locking failures. We don't have great support for that in Hibernate or Seam.The other useful option
First Commit Wins
is doable with exception handling in pages.xml and redirect/action/event/message, etc. What I am missing is handling it without a redirect but a partial page refresh, not sure that works.So the best you can do right now without a lot of extra coding is tell your users
Oops, somebody modified this while you worked on it
and ask them to use the Back button and copy the stuff they want to rescue. Then they need to (somehow) call a reset action on the conversation and start over from the beginning. This is less than ideal than a nice merge dialog that opens without a redirect. -
8. Re: StaleObjectStateException return to same page
coralfe Apr 10, 2008 1:33 PM (in response to coralfe)Our database calls are handled in a separate class which gets injected and that gets its entityManager injected with @In. Perhaps seam is reinjecting when hibernate's entity manager bombs, as I am able to continue without problem. I don't even lose my conversation.
This might also explain why I have never been able to actually catch the StaleObjectStateException!!!
I don't know seam's innards well enough to comment.
I am not doing anything specific with transactions. Seam is handling them and rolling back as required. -
9. Re: StaleObjectStateException return to same page
eirirlar Apr 10, 2008 2:52 PM (in response to coralfe)
Perhaps seam is reinjecting when hibernate's entity manager bombs.Although it would be a great feature if seam could do this, unfortunately it's not what happens (check the object id of your session or entityManager in a debugger). That's why I had to write the code above to do it myself for a given conversation.
as I am able to continue without problem.
Although you haven't experienced problems yet, you might do so unexpectedly later in the conversation (according to the statement from the hibernate book above).
I don't even lose my conversation.
Unless you end it explicitly with an <end-conversation/> in pages.xml or something similar, you won't lose it. But your hibernate session will still be in bad shape.
This might also explain why I have never been able to actually catch the StaleObjectStateException!!!
I say you mentioned entityManager. If you're not using a hibernate session (but a JPA entitymanager instead), you won't get StaleObjectStateException but OptimisticLockException.