On 10/2/07, syg6 <[EMAIL PROTECTED]> wrote:

>
> Thanks for your response Mike. I think you must have copy-pasted from
> another
> post or something, I am not working with a Country object. But I think
> your
> idea applies to both of my scenarios.


Correct. It is a copy and paste from the relevant post on the thread.



> In scenario (1) I already have a PropertyEditor defined for StreetSection.
> It looks like this:
>
> public class StreetSectionPropertyEditor extends PropertyEditorSupport
> {
> public void setAsText(String id) {
>      StreetSection streetSection = streetSectionManager.get(new Long(id));
>      setValue(streetSection);
> }


Please be careful about handling null values - you may/may not need this
depending on the details of your implementation. You do need a getAsText
method to ensure the field gets properly populated with the id for an
existing establishment.



> And it seems to work fine. I don't have a getAsText() defined and it has
> worked until now. But I am unsure of what I should use in the
> establishmentform.jsp. Should I use:
>
> <form:hidden path="streetSection" id="streetSection" /> or


This is the one you should use as it will use your property editor to
correctly bind your object to the existing instance in your database.



> <form:hidden path="streetSection.id" id="streetSection.id" /> ?


This will create a new StreetSection and attempt to save it. Presumably this
is not what you want?



> It was working ok using 'streetSection' instead of 'streetSection.id' but
> I
> had problems when saving a NEW establishment (it worked fine when saving
> an
> existing Establishment curiously enough ...), 'can't save a transient
> object' error. Could this be because I don't have getAsText() defined?


Probably due to a cascade being set on the establishment object. Try without
cascading save on the relationship. Judging by your jsp code this should
always be null for a new establishment object?

Perhaps you could post the details of the error and we can try and help?



> In scenario (2), how would I go about creating an
> EstablishmentContainerPropertyEditor? What I would need to do is tell
> Spring, 'Hey! Create an EstablishmentContainer object with '1' for
> idEstablishment, '2' for idContainer and '50' for quantity, and add it to
> the list of EstablishmentContainers, using values from the .jsp, either a
> multi-select or hiddens. But the setAsText() method takes only one string,
> usually an id. Do I need to override some other method in
> PropertyEditorSupport?


Property editors only do one thing: Text -> Object and Object -> Text. So
they are useful if you want to build up one or more relationships between
the object you are editing in the form and existing objects in the database.
If what you are talking about is creating a new set of objects, then your
form needs to address that -> your form would create new
EstablishmentContainer objects and use property editors to build the
relationship between EstablishmentContainer -> Establishment and
EstablishmentContainer -> Container. Exactly how to go about this largely
depends on how you want to manage the whole lot on the jsp page. If you have
something that works, then that is the best way!

Spring does have the ability to bind to elements in an ordered list by using
[index] type syntax, e.g. establishmentContainer[1]. Doing a Google search
on 'Spring MVC bind list' will bring up a whole list of sites that discuss
this in more detail.

Mike.


> I think this is the way to go though, just not sure how to do it.
>
> Thanks!
> Bob
>
>
>
>
> Mike Horwitz wrote:
> >
> > I believe you could resolve both cases by registering custom editors in
> > your
> > controllers - this would allow Spring MVC to automatically convert
> between
> > the object and its string representation. See the thread on this
> > discussion
> > for more details http://tinyurl.com/3yghfd:
> >
> > You are going to need to provide *Spring* *MVC* with a way to get from
> an
> > id
> > to a country and vice-versa.  As you correctly point out this is done by
> > registering a custom property editor in your controller. To do this you
> > need
> > to:
> >
> > 1) Extend the class *PropertyEditorSupport* to create the property
> editor:
> >
> http://java.sun.com/j2se/1.5.0/docs/api/java/beans/*PropertyEditorSupport*.html
> > <
> http://java.sun.com/j2se/1.5.0/docs/api/java/beans/PropertyEditorSupport.html
> >
> >
> > You need to override the getAsText() and setAsText() methods. The first
> > should call getValue() and return the id as text, and the second should
> > accept a text id and call setValue() on the editor with the
> corresponding
> > country object.
> >
> > 2) You then register this custom editor using one of the appropriate
> > methods
> > on your controller: initBinder() see api on http://tinyurl.com/2sutrm
> >
> > And it should all work like magic....
> >
> > Mike.
> >
> >
> > On 10/2/07, syg6 <[EMAIL PROTECTED]> wrote:
> >>
> >>
> >> I have a couple scenarios, one typical the other not so much, that I am
> >> trying to implement as quickly and easily as possible.
> >>
> >> The first is pretty straight-forward:
> >>
> >> @Entity
> >> public class Application
> >> ...
> >> private StreetSection streetSecion;
> >> ...
> >> @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
> >> @JoinColumn(name="streetSection", nullable=false)
> >> public StreetSection getStreetSection()
> >> {
> >> return streetSection;
> >> }
> >>
> >> In my form, which is the correct way to do the input?
> >>
> >> <form:hidden path="streetSection" id="streetSection" />
> >>
> >> or
> >>
> >> <form:hidden path="streetSection.id" id="streetSection.id" />
> >>
> >> In my testing I have found that they both work but each one has its own
> >> little quirks. For example, if I use 'streetSection.id', when it's a
> new
> >> Application the page crashes because streetSection.id is null. So I
> have
> >> to
> >> put a <c:if> in there and if it's null just use a normal <input
> >> type='hidden'> tag.
> >>
> >> If I use 'streetSection' I believe (I've done so many tests I forget
> ...)
> >> that Hibernate is giving me 'can't save transient object' errors.
> Anyway,
> >> just curious what the best practice is.
> >>
> >> The other scenario is more complicated. I have an object,
> Establishment,
> >> and
> >> another, Container, and they both have a list of EstablishmentContainer
> >> objects, which saved in a join table that has an attribute, quantity.
> So
> >> each POJO, Establishment and Container, have a OneToMany relationship
> >> with
> >> EstablishmentContainer, and EstablishmentContainer has a ManyToOne
> >> relationship with both Establishment and Container. This is apparently
> >> the
> >> best way to map join tables with attributes.
> >>
> >> @Entity
> >> public class Establishment
> >> ...
> >> private List<EstablishmentContainers> establishmentContainers;
> >> ...
> >> @OneToMany(mappedBy="establishment", fetch = FetchType.EAGER, cascade =
> {
> >> CascadeType.PERSIST, CascadeType.MERGE })
> >> public List<EstablishmentContainer> getEstablishmentContainers()
> >> {
> >> return establishmentContainer;
> >> }
> >>
> >> @Entity
> >> public class Container
> >> ...
> >> @OneToMany(mappedBy="container")
> >> public List<EstablishmentContainer> getEstablishmentContainers ()
> >> {
> >> return establishmentContainers;
> >> }
> >>
> >> @Entity
> >> public class EstablishmentContainer extends
> >> {
> >>        private Long id;
> >>        private Establishment establishment;
> >>        private Container container;
> >>
> >>        private int quantity;
> >> ...
> >> @ManyToOne
> >> @JoinColumn(name="idEstablishment")
> >> public Establishment getEstablishment()
> >> {
> >> return establishment;
> >> }
> >>
> >> @ManyToOne
> >> @JoinColumn(name="idContainer")
> >> public Cubo getContainer()
> >> {
> >> return container;
> >> }
> >>
> >> @Column(name="quantity")
> >> public int getQuantity()
> >> {
> >> return quantity;
> >> }
> >>
> >> In my EstablishmentFormController do I have to do the following for
> each
> >> EstablishmentContainer created in the page:
> >>
> >> 1. instantiate an EstablishmentContainer object
> >> 2. fill it it request parameters by hand
> >> 3. add it to a List
> >> 4. assign that list to my Establishment object
> >>
> >> ... for the EstablishmentContainers list to be properly saved when I do
> >> an
> >> establishmentManager.save()?
> >> This is what I am doing currently and it works but it seems to me that
> if
> >> I
> >> put the following in my jsp:
> >>
> >> input type="text" id="establishmentContainers.container.id"
> >> input type="text" id="establishmentContainers.establihsment.id"
> >> input type="text" id="establishmentContainers.quantity"
> >>
> >> Spring should be able to populate the List of EstablishmentObjects
> >> automatically, just as in the first example it populates my
> >> Application.StreetSection object when I put a
> >>
> >> input type="text" id="application.streetSection"
> >>
> >> element in the page. If it's not possible I can keep doing it the way I
> >> currently do, I just don't want to reinvent the wheel.
> >>
> >> Sorry for the long post. I look forward to any and all responses.
> >> Bob
> >>
> >> --
> >> View this message in context:
> >>
> http://www.nabble.com/Best-way-to-save-ManyToOne-relationships-with-Hibernate-and-Spring-MVC-tf4553758s2369.html#a12995187
> >> Sent from the AppFuse - User mailing list archive at Nabble.com.
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/Best-way-to-save-ManyToOne-relationships-with-Hibernate-and-Spring-MVC-tf4553758s2369.html#a12996194
> Sent from the AppFuse - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>

Reply via email to