Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Adding order / line items with Spring MVC

  1. #1
    Join Date
    Aug 2004
    Posts
    123

    Default Adding order / line items with Spring MVC

    I feel I'm reinventing the wheel with this one and wonder what others are doing, as it's such a common requirement.

    I have a form for inputting an Order. I want the user to be able to add LineItems to that order by clicking a link or button. Clicking this would take them to a LineItem input form, and when they saved this, they would go back to the Order form, in which a table of LineItems which featured the latest addition would be displayed.

    The question is, what happens to the Order when the user moves to the LineItem input form? Is it processed by processFormSubmission (I'm using a SimpleFormController) and stored in the session and until such time as it needs to be displayed again? I feel there must be an inbuilt mechanism in Spring MVC for handling this kind of thing which I have missed. I'd love to see more examples of Spring MVC use other than the JPetstore and Petclinic, showing some more 'real world' uses of the techniques.

  2. #2
    Join Date
    Jul 2005
    Location
    Russia
    Posts
    118

    Default

    Clicking link will issue a GET request, and no form submission will be in this case. Clicking button will depend on the button type attribute. If it is 'submit', then order form will be submitted.
    And of course, you can submit your Order form in any case using javascript.
    I would suggest staying with two SimpleFormController immplementations (one for Order, the other for LineItem). In this case you will need to store your information in the database after each request.
    If you prefer to save information at once on the Order page, you'll need an explicit session form to "link" your controllers, or AbstractWizardFormController implmentation for both pages.

  3. #3
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by EndlessWinter
    Clicking link will issue a GET request, and no form submission will be in this case. Clicking button will depend on the button type attribute. If it is 'submit', then order form will be submitted.
    Submitting a form can be done via GET if you specify method="get" in your form.

    Quote Originally Posted by EndlessWinter
    I would suggest staying with two SimpleFormController immplementations (one for Order, the other for LineItem). In this case you will need to store your information in the database after each request.
    If you prefer to save information at once on the Order page, you'll need an explicit session form to "link" your controllers, or AbstractWizardFormController implmentation for both pages.
    Both of these ideas are excellent. You might also want to look at Spring Web Flow.

  4. #4
    Join Date
    Aug 2004
    Posts
    123

    Default

    Quote Originally Posted by EndlessWinter
    Clicking link will issue a GET request, and no form submission will be in this case. Clicking button will depend on the button type attribute. If it is 'submit', then order form will be submitted.
    And of course, you can submit your Order form in any case using javascript.
    Hmm, I'm sorry but I think I need a bit more hand-holding through this one - I don't get it. Surely if I issue a GET request from a link on my Order page, without a form submission, I will merely lose the details entered onto the order page, as they will never make it to the server? What I was imagining would be the flow would be that an Add/Edit Line Item button or link would post the Order to the server, stick it in the session and then redirect to the entry form for Line Item. If the user clicked the Save button having entered the details, the Line Item would be posted to the server, the Order object would be retrieved from the session, the new LineItem would be added to the Order's lineItems Collection property and the user would be redirected to the edit order screen they came from, populated from the Order object in the session (including the LineItems).

    I'm sure there are hooks in Spring MVC to make this kind of thing easy for me, without having to explicitly work with session objects, etc. I just don't know quite where to look.

  5. #5
    Join Date
    Jul 2005
    Location
    Russia
    Posts
    118

    Default

    Unfortunately, i don't know such hooks, but all this process is not so hard to implement:
    first, on the Order page the link to Add/Edit Line Item will be a javascript with form.submit() expression.
    second, your two pages can share the same command class, and you can put the instance of this class into the session in the formBackingObject of the Order controller. If it is found there, then you are already editing the order, if it is not found, you are entering this page for the first time.

    And you can definetely look at Spring Web Flow, though i have no experience with it.

  6. #6
    Join Date
    Aug 2004
    Posts
    123

    Default

    Quote Originally Posted by EndlessWinter
    second, your two pages can share the same command class, and you can put the instance of this class into the session in the formBackingObject of the Order controller. If it is found there, then you are already editing the order, if it is not found, you are entering this page for the first time.
    I must confess I'm having some difficulty getting this one sorted. This is where I'm at. I have 2 controllers, an OrderController and a LineItemController. Let's say the user clicks a link to add a line item when in the order page. The link URL, /addLineItem.htm, is mapped to the OrderController. In the OrderController's processFormSubmission I check the value of a request parameter, 'dispatch', which tells me that the request was to add a related line item, so instead of calling super.processFormSubmission, I store the current Order object in the session, under the command name ('order') and redirect to an edit line item URL, picked up by the LineItemController. In the LineItemController's formBackingObject method, I retrieve the current Order object from the session, which allows me to display certain values from the parent Order record in the LineItem edit form. When the user saves this LineItem record, in the LineItemController's onSubmit method I add the LineItem record to the Order's lineItems collection, put the Order record back in the session and redirect to the Order edit screen. At this point, I would hope my new LineItem would be there but it isn't. Is this because Spring is not actually displaying the same Order object as I have just stored in the session, but a different version stored under its own name?

    This all seems horribly complicated, but what I'm trying to achieve is a very simple thing, which makes me feel I must be reinventing the wheel in a particularly slow and painful way, when there's already a perfectly good wheel sitting there for me to use which I don't know about.

    Basically, what I am trying to achieve boils down to this: I want the ability to add a parent record in one form, and then add child records in another form, which get added to the parent record, with the whole lot being saved or cancelled en masse. I don't want to have to save the parent record to the database before adding the child records, nor do I want to have to save the child records to the database unless the parent record is also saved. The LineItems are only relevant in the context of the Order, so I want the whole transaction cancelled or rolled back in one go.

    How do others do this? Is there some online example I could follow?

  7. #7
    Join Date
    Aug 2004
    Posts
    123

    Default

    Quote Originally Posted by jonmor
    I would hope my new LineItem would be there but it isn't.
    Actually it is - there was another error which was preventing its display. I still don't feel I've gone about this the right way though...

  8. #8
    Join Date
    Jul 2005
    Location
    Russia
    Posts
    118

    Default

    Well, your way seems to me quite correct. And you can save the order object from your session only when user press some "Submit and save" button on the Order page.

  9. #9
    Join Date
    Aug 2004
    Posts
    123

    Default

    Quote Originally Posted by EndlessWinter
    Well, your way seems to me quite correct. And you can save the order object from your session only when user press some "Submit and save" button on the Order page.
    Exactly. Well, you've given me some confidence to persevere, anyway.

    I'm just now wrestling with another little related problem which I'd welcome any input on. After the user has saved the LineItem and gone back to the Order page, they may well want to edit this or another LineItem from the list on the Order page. Clearly they need to be able to click on an Edit link which will pull up the correct LineItem. What I had for this originally, though, will not work - the 'id' property of the LineItem was used in the link to uniquely identify the LineItem to be edited. But of course this id does not exist until the LineItem is saved as part of the 'lineItems' collection in the Order object. (I'm using the 'native' Hibernate generator class, with MySQL, which means that the id value only gets populated when the record is persisted to the database). No problem, I thought - just use the index within the collection instead. But no go there either, as I'm using Sets (which are unordered), and I'm reluctant to change the collection type to a List unless I have to (Sets seem much the simplest way of doing one-to-many mapping in Hibernate). So I don't have an index into the collection.

    This is getting frustrating!

  10. #10

    Default

    Quote Originally Posted by jonmor
    Exactly. Well, you've given me some confidence to persevere, anyway.
    Have you considered AbstractWizardFormController or WebFlow, as was suggested above? AWFC probably requires least work, and it'll probably feel more right than two controllers communicating explicitly via a session attribute.

    Quote Originally Posted by jonmor
    I'm reluctant to change the collection type to a List unless I have to (Sets seem much the simplest way of doing one-to-many mapping in Hibernate).
    Taken a look at the <bag> mapping in Hibernate? It will produce a List on the Java end without requiring an explicit index-column on the db end. Or, as the Hibernate docs says: "If your table doesn't have an index column, and you still wish to use List as the property type, you should map the property as a Hibernate <bag>."

    You can change from Sets og Lists/bags by changing the Hibernate mapping from <set> to <bag> and changing the JavaBean property from Set to List. That's all, if I remember correctly.
    Last edited by martinl; Feb 19th, 2006 at 08:32 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •