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#a13507645
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