5 Replies Latest reply on Mar 8, 2007 1:23 AM by cja987

    Rollback exceptions without ending the conversation

    enazareno

      Hi,

      I am developing a CRUD application. When I start editing a bean, I begin a conversation. I do some other transactions that spans multiple pages. The conversation ends when I save successfully. If there are database exceptions that occur, I would like to display the same page where the error occured with some matching message without ending the conversation. I tried the exceptions.xml as in the docs, but it redirects it to an error page and it seems you need to end the conversation. If I end the conversation, I cant get back to my current conversation and lose the changes I've made. This sounds a very basic functionality but I have been struggling with this. If somebody has worked out a similar problem, I'd appreciate it a lot if you can help me out. Thanks.

      Regards,

      Elmo




        • 1. Re: Rollback exceptions without ending the conversation
          gavin.king

          JPA does not support recovery of the persistence context when a txn fails.

          You should always end the conversation after you fail to access the database. Otherwise you can be left with inconsistent state b/w memory and the database.

          • 2. Re: Rollback exceptions without ending the conversation
            enazareno

            Hi Gavin,

            Thanks for the reply. Common database errors like constraints, uniqueness etc. So what is your recommended approach in this case?

            1. Provide custom validation interceptor to handle chcking of the constraints. One needs to anticipate all the possible database errors though.

            Or

            2. Make the error happen, end the current conversation and provide a way to recreate back the conversation and position to where you left off (Sounds like jbpm doesn't it?). But its a normal CRUD and not a worfklow app so I think a business process is an overkill. Is there a way we can re-create the conversation? Is this what propagation does?

            Regards,

            Elmo

            • 3. Re: Rollback exceptions without ending the conversation

              Propagation won't recreate the conversation, and your conversation is still active if you didn't end it yourself. However, your entityManager is toast, so you need a new one, and that's usually done with a new conversation. It should be possible to recreate the entityManager within the current conversation and merge any detached instances into the new one, but the details elude me (hell, I can't even manage to use merge() correctly).

              I do number 1, and yeah I find it a maddening reminder of both JPA and JTA's inadequacies (JTA because it doesn't support nested transactions, which would more or less fix this problem).

              • 4. Re: Rollback exceptions without ending the conversation
                enazareno

                Hi,

                Thanks for pointing that out. Here is my sample code

                 @In
                 EntityManager em;
                
                 @In
                 UserList userList;
                
                 boolean isnew;
                
                 @Out
                 User user;
                
                 @Begin( id="#{user.id}" )
                 public void edit() {
                 user = em.merge(userList.getSelectedUser());
                 isnew = false;
                 }
                
                 @End
                 public void save() {
                 if(isnew)
                 em.persist( user );
                 else
                 em.merge( user );
                 userList.refresh(); //can also use event for this
                 isnew = false;
                 }
                


                The conversation actually ends when I press save. However it is my understanding that you cant put a try catch inside the save because the entity manager is flushed only when it ends so at this point there is no error yet? Is this correct? Let's say I'll just accept that limitation and I want to create another conversation instead. I've already specified the conversation id, can't I just use that as a reference to my new conversation that I will create? Or is there no chance to get back to that conversation?

                I agree with you, this seems like a complex solution and I'd prefer number one too. It just kinda reminds me of the old days developing Clipper applications where you manage this kind of validation yourself. With client-server development, you are encouraged to let the database handle this. Now its back. Life's a cycle isnt it? so retro :)


                Regards,

                Elmo





                • 5. Re: Rollback exceptions without ending the conversation

                  A conversation isn't normally destroyed when an exception is thrown out of an @End method, so you should be able to redirect to an error page that lets you get back into your edit screen.

                  If you prefer to catch inside the save method, you should have save() return a String for the outcome, and return null if you don't want it to actually end. It's in the docs for the @End annotation, at http://docs.jboss.com/seam/latest/reference/en/html/annotations.html

                  Of course if you catch the exception in the save method, you still have to do the recovery bits. If you make it actually work, I'd love to see what the solution was.