7 Replies Latest reply on Aug 2, 2010 9:46 PM by Brian Raymond

    Seam CRUD app - updating one table from another

    Brian Raymond Newbie

      I jumped into Seam 2 a couple of weeks ago to implement a web app around a set of three tables I defined to support a fairly straightforward report system. I have a table of products, a table of reports, a third table containing a list of products in a report using the PK or the product table and PK of the report table.

      I used seam gen and have something I can manipulate the tables with. I customized some things, added a restriction to support a nested datatable view of products in a report and those things work great.

      Now I'm getting wrapped around the axle on something that seemed simple at first but is really kicking my butt. I have a modalwindow I bring up from the reports view with a list of products so they can be selected by the user. To make it work I want to call something from the product row that will update the third table with the appropriate information when a link or commandbutton is pressed (whatever I need). I have the data I need from the view but for the life of me I do not understand how I can populate three values for the third table and commit them to the DB using either the generated *Home class or an action I create myself. I am completely lost, any guidance would be appreciated.

        • 1. Re: Seam CRUD app - updating one table from another
          Sean Tozer Newbie

          That doesn't seem too hard, but I'm afraid I didn't quite follow what it is that you want to have happen. Could you perhaps run through an example?

          Do you basically have two tables, products and reports, and then a third table that links them in a many-to-many relationship? And you want to have a button that causes a product to be linked to a report?

          Don't think about it so much in terms of the database, just think about how you want the entities to be related. So, you could do something like calling an action on the reportHome component that takes a productID. It then creates a productHome, using that ID to fetch the right entity, and then flushes the whole thing back to the database. Assuming the entities are set up as many-to-many with a mapping table, that should pretty much do it right there.

          • 2. Re: Seam CRUD app - updating one table from another
            Brian Raymond Newbie

            You describe exactly what I want to do, I think I am more lost on the mechanics of how to make it happen then anything.

            I have played with s:link and commandButtons and see how to put them on a page and link to another page or call an action but I do not quite have my hands around how to put it together in this case. For example how do I put something in the xhtml page to use the pieces of data I have on the page to create and persist the object, do I somehow pass them in the command button or is there another way that makes sense. It seems stupid when I read it, I just haven't been able to turn the light bulb on for myself.

            • 3. Re: Seam CRUD app - updating one table from another
              Brian Raymond Newbie

              In hindsight I see it was right in front of me the whole time, I used a commandbutton with actionparams to fill out the bean and persist it.

              Sean, Thanks for jogging my memory.

              I however have a related follow-up. In the *List view for a table I want to add a button to remove the row from the DB and rerender it. I tried the following mimicing the successful persist however it appears to do nothing

                          <a4j:commandButton value="Remove Product"  reRender="itemsList" action="#{itemsHome.remove()}">
                               <a4j:actionparam name="reportnum" value="#{_items.id.reportnum}" assignTo="#{itemsHome.instance.id.reportnum}"/>
                               <a4j:actionparam name="productid" value="#{_items.id.productid}" assignTo="#{itemsHome.instance.id.productid}"/>
                               <a4j:actionparam name="lin" value="#{_items.lin}" assignTo="#{itemsHome.instance.lin}"/>

              • 4. Re: Seam CRUD app - updating one table from another
                Sean Tozer Newbie

                I think what you would want to do is get the itemsHome to have the correct entity associated with it when remove gets called. Your itemsHome should have some method on it that lets you set the primary key, which then delegates to setId. That's what loads the actual object (which is then stored in .instance). If nothing's been set as the current object, it'll just try to remove something that wasn't in the database anyway, which won't do anything.

                So it'd be something like

                            <a4j:commandButton value="Remove Product"  reRender="itemsList" action="#{itemsHome.remove()}">
                                 <a4j:actionparam name="itemsId" value="#{_items.id.itemsId}" assignTo="#{itemsHome.itemsId}"/>

                I don't know what your actual ids are named there, but that's the idea. You need to get the actual entity loaded in in order to remove it. setItemId (or whatever) should just call setId() in the parent entityHome class, which then does all the work of pulling that instance out of the database.

                • 5. Re: Seam CRUD app - updating one table from another
                  Brian Raymond Newbie


                  Thanks for the help, it's been very useful.

                  I have it reporting  java.lang.IllegalArgumentException: Removing a detached instance when calling remove. At this point I assume I'm running into issues with my conversation and scope. I'm not sure how to troubleshoot but thus far I haven't touched any of that so I assume I need to adjust.

                  • 6. Re: Seam CRUD app - updating one table from another
                    Brian Raymond Newbie

                    I changed the following, which was throwing the detached instance exception:


                    to something matching what you described:

                               <a4j:commandButton value="Remove Product"  reRender="itemsList" action="#{itemsHome.remove()}">
                                     <a4j:actionparam name="itemsId" value="#{_items.id}" assignTo="#{itemsHome.id}"/>

                    At first it looks like it was working with the log reporting:

                    21:09:52,866 INFO  [lifecycle] WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
                    sourceId=null[severity=(INFO 0), summary=(Successfully deleted), detail=(Successfully deleted)]

                    however there isn't any SQL run against the database to remove the actual row, I assume I'm missing something really small to actually make it work.

                    • 7. Re: Seam CRUD app - updating one table from another
                      Brian Raymond Newbie

                      This has definitely been a learning experience for a C and (somewhat) Java guy that hasn't ever really worked in an environment like this. I love how easy it makes things but it's still an uphill battle.

                      I'm reviving this thread with a reply because I just jumped back on this and found that the above post with the itemsHome.remove doesn't seem to be working because itemsHome isn't managed (inferring it from the use of that attribute on the delete actions).

                      I think I need to do more reading but on page load I wire the component so wouldn't it be managed or is there something else that must happen? Thanks.