1 2 Previous Next 20 Replies Latest reply on Jun 10, 2007 3:14 PM by beligum

    My list of questions: Seam validation, transactions and exte

    beligum

      Hi all,

      I know this is a much-asked topic/question, but it would be cool if someone takes the time to explain a thing or two to me. Don't think I'm lazy; I've been reading up on this all day, I just need some clarification ;-)
      I also hope this is the right forum to ask, since it's pretty much seam-specific, so please excuse me if it's not.

      I have this very well documented scenario: a user clicks something he wants to edit, changes some things, and sends the changes back to the DB (the "multipage wizard pattern").

      I have the following installed: a stateful session bean that keeps track of the object that is to be edited, an persistence context, a method that init's the edit-session and one that writes the changes to the db.
      I begin a conversation in the init() method and load the selected object into a variable of the SSB. The conversation is ended in the update() method.

      Now my questions:

      0. If I inject (@In) my EntityManager in Seam, it holds an extended persistence context, right?

      1. If I call merge() or not in the update() method, it doesn't make any difference, the changes are always written to the DB. Why is that?

      2. I use seam-validation that checks my data, but when something goes wrong in the update() method, a rollbackException is thrown, but my changed data is still written to the DB. How come?

      3. If I would like to solve the issue in question #2, if @Begin(flushMode=MANUAL) the only solution? If you have an answer here, please elaborate regarding @TransactionAttribute and @Rollback, because this is all but clear to me. For instance, why doesn't my @Rollback on the update() method work if something goes wrong in that method?

      4. Is this solution: http://docs.jboss.org/ejb3/app-server/tutorial/extended_pc/extended.html the same as @Begin(flushMode=MANUAL)?

      5. Is it normal I can't use <s:convertEntity /> if I use @PersistenceContext instead of an injected (@In) entity manager?

      6. Is there a way to specify flushMode=MANUAL in the <begin-conversation> tag of pages.xml?

      7. A bit of a general question: in my scenario (without the manual flushmode), where are the transactions started/ended, and where will throwing runtime exceptinos do any rollback on the changed data?

      8. If I would like to post my findings of today in a wiki, what's the best one I can choose?

      I hope I can help others out with my questions too, because this is supposed to be general knowledge, but it's hard to get your thoughts around these concepts if one comes from a non-ejb3 environment, directly to seam.

      kudos to those who find the time and helpfulness to answer my questions.

      b.

        • 1. Re: My list of questions: Seam validation, transactions and
          pmuir

           

          "beligum" wrote:
          0. If I inject (@In) my EntityManager in Seam, it holds an extended persistence context, right?


          A persistence context scoped to (current) conversation will be injected. An extended persistence context is only scoped to the current SFSB whilst SMPC allows *any* bean participating in the to have the same pc

          1. If I call merge() or not in the update() method, it doesn't make any difference, the changes are always written to the DB. Why is that?


          Because your entites are managed. Read up on this in the HEM manual, or a book on JPA.

          [quote[4. Is this solution: http://docs.jboss.org/ejb3/app-server/tutorial/extended_pc/extended.html the same as @Begin(flushMode=MANUAL)?

          It's not the same, but has a similar outcome (you used to have to use it with Seam). Manual flushmode is neater (much).

          5. Is it normal I can't use <s:convertEntity /> if I use @PersistenceContext instead of an injected (@In) entity manager?


          • 2. Re: My list of questions: Seam validation, transactions and

             

            "beligum" wrote:
            Hi all,
            6. Is there a way to specify flushMode=MANUAL in the <begin-conversation> tag of pages.xml?


            Yes-- just specify flush-mode="MANUAL"

            • 3. Re: My list of questions: Seam validation, transactions and
              beligum

              Hi guys, thanks for the replies, this is great stuff.

              Any chance anyone wants to explain what happens if a RuntimeException is thrown in my update() method? This is the only major conceptual hurdle I'm still struggling with. My common sense tells me, when that method 'fails', the update model value phase should be rolled back too, but it doesn't.

              b.

              • 4. Re: My list of questions: Seam validation, transactions and
                gavin.king

                 

                "beligum" wrote:
                0. If I inject (@In) my EntityManager in Seam, it holds an extended persistence context, right?


                If there is a long-running conversation, yes.

                "beligum" wrote:
                1. If I call merge() or not in the update() method, it doesn't make any difference, the changes are always written to the DB. Why is that?


                merge(x) is a no-op if x already belongs to the persistence context (which is usually the case when you have an extended persistence context.

                "beligum" wrote:
                2. I use seam-validation that checks my data, but when something goes wrong in the update() method, a rollbackException is thrown, but my changed data is still written to the DB. How come?


                Um, I don't really follow this. Seam validation does not throw rollback exceptions.

                Probably the reason the changes are already persistent is because they were applied to the model, and then persisted, on previous async validation requests.

                "beligum" wrote:
                3. If I would like to solve the issue in question #2, if @Begin(flushMode=MANUAL) the only solution?


                No, there are two other solutions.

                (1) use <a:support bypassUpdates="true"/>
                (2) disable Seam transaction management and use EJB transaction management instead

                I do not recommend (2).

                "beligum" wrote:
                If you have an answer here, please elaborate regarding @TransactionAttribute and @Rollback, because this is all but clear to me. For instance, why doesn't my @Rollback on the update() method work if something goes wrong in that method?


                Probably it does, but the changes were persisted from a previous async validation request. But I can't really say, from the information given.

                "beligum" wrote:
                4. Is this solution: http://docs.jboss.org/ejb3/app-server/tutorial/extended_pc/extended.html the same as @Begin(flushMode=MANUAL)?


                That is one good solution, yes. Another possibility is bypassUpdates="true".
                It is a (fixed) mistake that seam-gen in 1.2.1 did not use bypassUpdates.

                I think you should start by trying bypassUpdates.

                "beligum" wrote:
                7. A bit of a general question: in my scenario (without the manual flushmode), where are the transactions started/ended, and where will throwing runtime exceptinos do any rollback on the changed data?


                I don't know for sure. Are you using TransactionSeamPhaseListener? If so, they are tied to the lifecycle of the JSF request, as in the docs.


                • 5. Re: My list of questions: Seam validation, transactions and
                  pmuir

                  Sorry about truncating my reply, I had to go out.

                  "beligum" wrote:
                  5. Is it normal I can't use <s:convertEntity /> if I use @PersistenceContext instead of an injected (@In) entity manager?


                  Yes. s:convertEntity uses an SMPC / Seam managed transactions to reload the entity from the PC. Unless you have a LRC in which you previously loaded the entity the reloaded entity won't be equal - you have to use ID equality (see http://hibernate.org/109.html). And I need to work out how to explain this better ;)

                  8. If I would like to post my findings of today in a wiki, what's the best one I can choose?


                  Any additions to http://wiki.jboss.org/wiki/Wiki.jsp?page=SeamProblemsFAQ are great, otherwise, you could use the above as the start of SeamPersistenceFAQ linked off the main wiki page :)

                  • 6. Re: My list of questions: Seam validation, transactions and
                    beligum

                    Thanks for your replies guys, you cleared out some confusing matter to me.
                    The quality of the community-helpdesk around Seam is most certainly one of the reasons it's adoption-rate is elevating so quickly.
                    I'll try to share my findings with other people, once I've catched up with some deeper stuff on JPA, like Peter suggested.
                    Thanks again.

                    • 7. Re: My list of questions: Seam validation, transactions and
                      beligum

                      Hi again.

                      I've done some debugging and found interesting results.

                      In my update-form, I have these input-controls (they're templated, but you get the point)

                      <ui:decorate template="/templates/t_form_text_entry.xhtml">
                       <ui:param name="id" value="newSpaceName" />
                       <ui:param name="label" value="#{messages['name']}" />
                       <ui:param name="value" value="#{selectedSpaceInstance.entityData.name}" />
                       <ui:param name="width" value="300px" />
                       <ui:param name="required" value="true" />
                       <ui:param name="validatorBean" value="#{spaceManager}" />
                       <ui:param name="validatorAction" value="validateSpaceName" />
                      </ui:decorate>
                      
                      <ui:decorate template="/templates/t_form_entry.xhtml">
                       <ui:param name="id" value="newSpaceCompany" />
                       <ui:param name="label" value="#{messages['company']}" />
                       <ui:param name="required" value="true" />
                      
                       <h:selectOneMenu id="newSpaceCompany" value="#{selectedSpaceInstance.entityData.company}" styleClass="input" style="width: 200px;"
                       required="true" rendered="#{not empty companyManager.possibleSpaceCompanies}">
                       <s:selectItems value="#{companyManager.possibleSpaceCompanies}" var="company" label="#{company.name}" />
                       <s:convertEntity />
                       </h:selectOneMenu>
                      </ui:decorate>
                      


                      They're both validated: the input box is required, and it's name is also checked for existence (#{spaceManager.validateSpaceName}). The combobox is only required.

                      When I submit my form like this (long-running conversation, TransactionSeamPhaseListener), the data-model is updated, even when the transaction rolls back. This must be caused by the validation of the combobox, because it acts as expected when I delete the combobox-input and let the inputbox-field untouched.

                      Could this be a bug, where <s:convertEntity/> (or <s:selectItems/> ?) updates the model, even when the transaction rolls back?

                      b.

                      • 8. Re: My list of questions: Seam validation, transactions and
                        pmuir

                        I think we still have some confusion here: JSF does

                        1) RESTORE VIEW
                        2) APPLY REQUEST VALUES (update the JSF component instances with the submitted values - localValue on EditableValueHolder) (no affect on your backing beans here)
                        3) PROCESS VALIDATIONS - run converters, then validators (this is the *only* point at which s:convertEntity is invoked)
                        4) UPDATE MODEL
                        5) INVOKE APPLICATION

                        - if an exception is thrown anywhere, then further stages are aborted.

                        Transactions (JTA) and JSF know nothing about each other - so whether the transaction rolls back or not has no effect on updating the model.

                        Anyway, I have never seen the effect you describe. Can you try doing this without all the ui:decorate stuff (just put the components on the page) and see if you still observer the same effect? If you do, please submit a runnable, simple example of this to JIRA and I'll take a look (without the templating stuff)

                        • 9. Re: My list of questions: Seam validation, transactions and
                          gavin.king

                          Um, where is your s:validate or s:validateAll??

                          I don't think you're doing any JSF validation at all! All you are getting is validators running when Hibernate tries to write to the database! (Hence the tx rollback.)

                          • 10. Re: My list of questions: Seam validation, transactions and
                            beligum

                            I tried to extract the functionality from my app and created a simple example out of it, just like Peter suggested.
                            Seems like all is well there. Validation occurs, and transaction rollback happens when an exception is thrown or the @Rollback is triggered.
                            Apparently, I'm doing something wrong elsewhere.

                            Gavin, I don't actually use Seam validation (yet), but JSF validation instead. Can this introduce any problems? It seemed to work fine in my simple app, so I don't think that's my cause of error. But then, I'm wrong about many things, apparently ;-)

                            Thanks for the quick reactions, I'll try to dig a bit deeper to find my bug. The pain is that, sometimes, the value is changes in the DB, but not always, which makes it very hard to determine the cause of error.
                            By the way: I'm causing the rollback artificially, just to test what will happen when something goes wrong while the update() method in invoked.

                            • 11. Re: My list of questions: Seam validation, transactions and
                              beligum

                              I'm getting strange behaviour, and my guess is it's caused because of my misunderstanding of conversations (yes, I've read through the entire manual and many other docs too :-).

                              I'll try to explain my 'workflow' in my own words, maybe I'm thinking wrong.

                              I log in (almost default authenticator) -> select a space (conversation starts, join=true) -> click to edit the space (another conversation starts, but join=true) -> do some modifications (action-method returns "failure" and has @Rollback(ifOutcome={"failure"})) ->back to my edit-form and I'm noticed that my transaction failed, but the changes were persisted -> if I do additional changes and click update, they aren't persisted to the database anymore (expected behaviour).

                              I find this a bit odd, and I don't fully understand why things happen the way they do. I'd be happy to post all of my related code, but don't know where to begin.

                              Damn, I feel like a noob here (although I'm not, at least not programatically ;-))

                              • 12. Re: My list of questions: Seam validation, transactions and
                                gavin.king

                                Well, I don't see any JSF validators in the code you have posted either....

                                • 13. Re: My list of questions: Seam validation, transactions and
                                  gavin.king

                                  BTW, when you say "the changes are persisted", how do you determine this? By looking in the database?

                                  • 14. Re: My list of questions: Seam validation, transactions and

                                    I played around with JSF validation for a few days, and I just couldn't get it play nicely with Seam. I ran into some bizarre problems with transaction management and I just said forget it--I resorted to just action-validation instead.

                                    "beligum" wrote:

                                    Gavin, I don't actually use Seam validation (yet), but JSF validation instead. Can this introduce any problems? It seemed to work fine in my simple app, so I don't think that's my cause of error. But then, I'm wrong about many things, apparently ;-)



                                    1 2 Previous Next