Upon further reflection it seems I need a ManyToMany, not OneToMany.
I changed my mappings accordingly:
Application POJO
private Set<Place> places;
@ManyToMany(
targetEntity=com.myco.myapp.model.Place.class,
cascade={CascadeType.PERSIST, CascadeType.MERGE},
fetch = FetchType.EAGER
)
@JoinTable(
name="applicationplace",
[EMAIL PROTECTED](name="idApplication")},
[EMAIL PROTECTED](name="idPlace")}
)
public Set<Place> getPlaces(){
return places;
}
Place POJO
private Set<Application> applications;
@ManyToMany(
cascade={CascadeType.PERSIST, CascadeType.MERGE},
mappedBy="places",
targetEntity=Application.class
)
public Set<Application> getApplications() {
return applications;
}
But the same thing is happening - The list page shows an Application for
every Place associated, and when I save it doesn't update the associated
Places. Bummer. Interestingly, if I omit the fetch=FetchType.EAGER, I get
the proper number of Applications in the list page. But the edit page dies,
saying that places is null.
I got this mapping straight out of the Hibernate reference manual. I'm not
sure what I am doing wrong ...
Bob
syg6 wrote:
>
> I do have a hidden 'id' field, and I haven't specified a cascade type.
>
> Mind you, when I save an Application it is NOT saving an additional
> Application in the database nor is it saving an additional record in the
> applicationplace table. It is performing an UPDATE in the application
> table and seemingly doing nothing in the applicationplace table.
>
> It seems that Hibernate is messing up the loading of the data (through
> some mapping mess-up on my part, no doubt). When I call
> applicationManager.getAll(), for a given Application A it is displaying (A
> x numP), where numP is the number of Places associated with the
> Application. It's as if it were performing a JOIN without specifying the
> correct FOREIGN KEY field in both tables.
>
> I'll keep digging ...
>
> Bob
>
>
> Michael Horwitz wrote:
>>
>> Two things to check:
>>
>> 1) You have a hidden field on your application form which stores the
>> application id. If not there Hibernate will save a new application every
>> time....
>> 2) Cascade is set to at least "save-update" for the relationship to
>> place.
>>
>> Mike.
>>
>>
>> On 8/16/07, syg6 <[EMAIL PROTECTED]> wrote:
>>>
>>>
>>> Asnwered my own damn question, didn't I? That's what happens when you
>>> spend
>>> 20 minutes typing up a question for a mailing list ... :)
>>>
>>> What I was missing: in the initBinder() method, instead of
>>>
>>> binder.registerCustomEditor(Place.class, ppe);
>>>
>>> it should be:
>>>
>>> binder.registerCustomEditor(Place.class, "places", ppe);
>>>
>>> I guess if you don't specify which field of the Object you wish to bind
>>> to,
>>> it tries to bind to all of them, or the entire Object. Nope, that won't
>>> work.
>>>
>>> Anyway, so it seems to be working in so much that if I choose 3 Places
>>> in
>>> the multi-select, in my ApplicationController, after casting my command
>>> Object:
>>>
>>> Application application = (Application) command;
>>>
>>> application.getPlaces() lists all 3. If I only select 2, it lists two.
>>> BUT
>>> it's not saving! All other fields get updated but not Places. The
>>> applicationplaces table still has the data from the sample-data.xml.
>>>
>>> Something fishy is definitely going on because in my
>>> applicationlist.jsp,
>>> If
>>> I associate 2 Places with an Application (using sample-data.xml), that
>>> Application shows up twice in the list of Applications. If I assign 3
>>> Places, it shows up 3 times. Hmmm ...
>>>
>>> I already listed my mapping for Application. I don't have a mapping for
>>> Place because I don't need to know which Application a Place is assigned
>>> to.
>>>
>>> Is my mapping somehow wrong? Could that be messing up the save and the
>>> list?
>>>
>>> Thanks,
>>> Bob
>>>
>>>
>>> syg6 wrote:
>>> >
>>> > Hello all.
>>> >
>>> > I am using Appfuse M5, Spring MVC + Hibernate. I have an object,
>>> > Application, that as a 1-many relationship with Place. The Application
>>> > Pojo looks like this:
>>> >
>>> > private Set<Place> places;
>>> >
>>> > @OneToMany (fetch = FetchType.EAGER)
>>> > @JoinTable(
>>> > name="applicationplace",
>>> > joinColumns = { @JoinColumn( name="idApplication") },
>>> > inverseJoinColumns = @JoinColumn( name="idPlace")
>>> > )
>>> > public Set<Place> getPlaces(){
>>> > return places;
>>> > }
>>> >
>>> > In the database I have 3 tables:
>>> >
>>> > Application
>>> > Place
>>> > ApplicationPlace
>>> >
>>> > When I create a Application I can assign 0-n Places to that
>>> Application.
>>> > When I save the Application I have to use a Custom Property Editor to
>>> tell
>>> > Spring how to convert each id in the Places multiple-Select into a
>>> Place
>>> > object, so a reference to it can be saved in the ApplicationPlace
>>> table.
>>> >
>>> > So far so good. I created a PlacePropertyEditor which looks like this:
>>> >
>>> > public class PlacePropertyEditor extends PropertyEditorSupport
>>> > {
>>> > private GenericManager<Place, Long> placeManager = null;
>>> >
>>> > public void setPlaceManager(GenericManager<Place, Long>
>>> placeManager)
>>> {
>>> > this.placeManager = placeManager;
>>> > }
>>> >
>>> > public void setAsText(String id) {
>>> > Place place = placeManager.get(new Long(id));
>>> > setValue(place);
>>> > }
>>> > }
>>> >
>>> > In my ApplicationFormController I have a setPlaceManager() method and
>>> it
>>> > is properly wired in my dispatcher-servlet.xml. Also in
>>> > ApplicationFormController I have overrided initBinder:
>>> >
>>> > protected void initBinder(HttpServletRequest request,
>>> > ServletRequestDataBinder binder)
>>> > {
>>> > PlacePropertyEditor ppe = new PlacePropertyEditor();
>>> > ppe.setPlaceManager(placeManager);
>>> > binder.registerCustomEditor(Place.class, ppe);
>>> > }
>>> >
>>> > But when I run testSave() in ApplicationFormControllerTest it fails.
>>> >
>>> > public void testSave() throws Exception
>>> > {
>>> > MockHttpServletRequest request = newGet("/applicationform.html");
>>> > request.addParameter("id", "1");
>>> >
>>> > ModelAndView mv = c.handleRequest(request, new
>>> > MockHttpServletResponse());
>>> >
>>> > Application application = (Application)
>>> > mv.getModel().get(c.getCommandName());
>>> > assertNotNull(application);
>>> >
>>> > request = newPost("/applicationform.html");
>>> > super.objectToRequestParameters(application, request);
>>> > request.addParameter("applicationCode", "updated application code");
>>> >
>>> > //request.addParameter("places", "1");
>>> >
>>> > mv = c.handleRequest(request, new MockHttpServletResponse());
>>> >
>>> > Errors errors = (Errors)
>>> > mv.getModel().get(BindException.MODEL_KEY_PREFIX + "application");
>>> > assertNull(errors);
>>> > assertNotNull(request.getSession().getAttribute("successMessages"));
>>> > }
>>> >
>>> > The line that fails is assertNull(errors); If I comment out the Custom
>>> > Property Editor it works. (But in the web page, without a Custom
>>> Property
>>> > Editor I get the typical error that I can't covert a Set to String) I
>>> have
>>> > tried adding request.addParameter("places", "1") to see if it was
>>> failing
>>> > because no idPlace was being sent in the request, but it fails either
>>> way.
>>> >
>>> > It seems I am missing a step when defining my Custom Property Editor.
>>> Do
>>> I
>>> > need to wire my PlacePropertyEditor in the application-context.xml?
>>> > According to Chapter 5 of the Spring 2.0 Reference Manual I do. But I
>>> > don't see that Appfuse does this with its Custom Property Editors;
>>> > BaseFormController's initBinder() method registers Custom Property
>>> Editors
>>> > for Integer, Long, byte[] and Date but they aren't wired anywhere.
>>> >
>>> > I am not sure exactly what is failing. I've tried putting log.debug()
>>> > statements in the code but they don't appear in the console or in my
>>> > surefire reports.
>>> >
>>> > Anyone have an idea as to what I might be doing wrong?
>>> >
>>> > Thanks,
>>> > Bob
>>> >
>>>
>>> --
>>> View this message in context:
>>> http://www.nabble.com/testSave-fails-using-custom-property-editor-tf4278929s2369.html#a12179616
>>> 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/testSave-fails-using-custom-property-editor-tf4278929s2369.html#a12180898
Sent from the AppFuse - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]