Whoops. Always read carefully before you post! After spending 20 minutes redacting my last message I re-read the message that I was responding to. I should have done this beforehand!
Dale suggests two solutions - either clear() the Set or delete each member. Well, as explained in my last message, calling aAndBManager.remove() for each element won't work, it causes errors. BUT loading, clearing and re-setting the Set DOES work! Many thanks and sorry for going on without having carefully read your post. The last bit of my message still stands though - how can I save new ObjectA objects, while at the same time associating ObjectB Objects, and have them properly saved in the database? I need the idObjectA column of the aandbjoins table to be properly saved but I don't have an idObjectA until AFTER calling save(). And even then, since the GenericDao calls persist(), it is not guaranteed to return an id for the new object being saved. (And at least in my case, even after calling save(), idObjectA is always null.) Thanks again! Bob syg6 wrote: > > Well what's curious is that with my other 'normal' ManyToMany (see my > previous post. ObjectA has a Collection of ObjectC) if from my ObjectA > form I delete all ObjectCs, the 'objectcs' Request parameter is 'null' and > Hibernate correctly deletes all ObjectC objects. > > But with my ObjectB Collection, this does not work, I assume because I am > doing a 'manual' ManyToMany, in other words ObjectA and ObjectB have a > OneToMany relation with AAndBJoin, and AAndBJoin has a ManyToOne to both > ObjectA and ObjectB. The behavior should be the same, no? If I send > 'null', it should delete all elements from the Collection, just as it does > with my ObjectC Collection. But it does not. > > At any rate, I've tried manually deleting all ObjectBs from the > Collection; In my ObjectAFormController onSubmit() I tried the following > (only when the 'objectbs' Request parameter is null): > > 1. Load ObjectA from database (to get existing ObjectB Collection). > 2. Use ObjectBManager to get() each ObjectB > 3. Use ObjectBManager to remove() each ObjectB > 4. Call ObjectAManager.save() > > And I get a 'deleted object would be re-saved by cascade (remove deleted > object from associations):' error, as I knew I would. And if I instead > call objectA.setObjectBs(null) I get a 'A collection with > cascade="all-delete-orphan" was no longer referenced by the owning entity > instance' error. > > The only difference I can see between the Collection of ObjectBs and > ObjectCs is that in my ObjectAFormController onSubmit(), after this line: > > ObjectA objectA = (ObjectA) command; > > ... if in the objectaform.jsp I have deleted all of the ObjectC elements > from the Collection, objectA.getObjectCs() is null. Correct! And Hibernate > goes on to delete these ObjectBs from the database. But if I have deleted > all of the ObjectB elements from the Collection, objectA.getObjectBs() is > NOT null; it has the 'old' data, the Collection as it existed before doing > the deletes. As such, Hibernate does not update the database. And I assume > that's also why if I try to manually delete the elements, I am getting an > error. > > Both Collections have a Custom PropertyEditor. The difference is that > ObjectC only implements setAsText(): > > public void setAsText(String id) > { > ObjectC objectC = objectCManager.get(new Long(id)); > setValue(objectC); > } > > whereas the Custom PropertyEditor for ObjectB, because I use my own Model > Object (AAndBJoin) to represent the Join, and has to grab a bunch of > values from text and hidden fields in the form to create AAndBJoin > Objects, implements setValue(): > > public void setValue(Object object) > { > // array of values sent from text/hidden inputs in form > String[] strings = (String[])object; > > Set<AAndBJoin> aAndBJoins = new LinkedHashSet<AAndBJoin>(); > > for (number of text/hidden inputs in the page) > { > AAndBJoin aAndBJoin = new AAndBJoin(); > aAndBJoin.setId(new Long(strings[0])); > aAndBJoin.setObjectA(objectAManager.get(new Long(strings[1]))); > aAndBJoin.setObjectB(objectBManager.get(new Long(strings[2]))); > aAndBJoin.setQuantity(new Integer(strings[3])); > aAndBJoins.add(aAndBJoin); > } > super.setValue(aAndBJoins); > } > > Anyway, the point is if I delete all ObjectC elements, ObjectC's Custom > PropertyEditor is not being called (because since it's null there's no > reason to call it) and when I call objectA.getObjectCs() I get null, ok. > But when I delete all ObjectB elements, even though its Custom > PropertyEditor isn't called either, when I call objectA.getObjectBs() I > get the old Collection info, before the delete. Which is why Hibernate > doesn't update the database, and why I get errors if I try to delete them > manually. > > Odd, inconsistent behavior, no? It seems that since I am using my own > Model Object (AAndBJoin) to represent the relation, I need to do something > else to make Hibernate aware that all elements have been deleted. But I > have no idea what! > > Incidentally, any ideas about the other problem? Where when I create a new > ObjectA and associate various ObjectB elements, those AAndBJoin Objects > are saved incorrectly, with idObjectA=null, because when I call > objectA.save() I still don't have an idObjectA? > > Thanks, sorry for the long post, > Bob > > > DNewfield wrote: >> >> syg6 wrote: >>> Something else I have noticed: deleting members of the AAndBJoin >>> Collection >>> seems to be working, more or less, now that I put the DELETE_ORPHAN >>> Hibernate Annotation. But there is one case where it does NOT work -- >>> when >>> you delete all of the elements. When you delete all of the elements, the >>> 'AAndBJoin' Request parameter is of course null. What Hibernate should >>> do in >>> this case is delete all elements. But what it in fact does, is nothing. >>> >>> It seems that in order for Hibernate to properly delete elements from a >>> Collection, at least one element has to be sent in the Request. Thus, if >>> you >>> had 4 and deleted 3, 1 element is sent in the Request and Hibernate >>> compares >>> the Collection before and after, and properly deletes 3. But if you >>> delete >>> all 4, in the Request 'null' is received, Hibernate seems to do no >>> comparison, and deletes nothing. Ugh. >> >> You need to detect this case, because assigning "null" to the the >> collection attribute is wrong--the appropriate answer is to retrieve the >> (hibernate managed) collection, and either remove each item from it or >> clear() the collection, then re-setting the (same) cleared collection to >> the attribute. >> >> -Dale >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [EMAIL PROTECTED] >> For additional commands, e-mail: [EMAIL PROTECTED] >> >> >> > > -- View this message in context: http://www.nabble.com/Many-to-many-collection-problem-tf4670322s2369.html#a13507971 Sent from the AppFuse - User mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]