Re: SOLUTION for M:N never delete or always delete, no matter auto-delete=true or auto-delete=false
I don't think so. First of all, OJB is always using RemovalAwareCollection if I don't specify collection-class (I don't know why). Since RemovalAwareCollection has a call to afterStore, the object is always removed. I'm working a months with this problem, and trying to fix it. But only with latest changes by thma (get by CVS HEAD) to make RemovalAware full working, I get into the light, and with the changes I've done, the MtoNTest#testDeletionFromBothTables and MtoNTest#testDeletionFromIntermediaryTable should (I've not tested, only with my own code) works fine. I wan't to enphatize two points: 1) cvs HEAD doesn't accept Collection subclasses anymore (except the ones that are Manageable). If you try to put a collection-class = java.util.ArrayList or anything else, you'll get ClassCastException due a ManageableCollection cast. 2) cvs HEAD with changes I've done make OJB M:N mapping work like expected, with or without proxies, and not ignoring the auto-delete=true/auto-delete=false. If you have some time, try the junit tests (specially the ones related to M:N) with changes proposed... I can even send you the changed files, if you wish. Is very important to me that OJB work fine with proxies and the M:N stuff. This is the reason I'm so boring about it... Best regards, Edson Richter - Original Message - From: Jakob Braeuchi [EMAIL PROTECTED] To: OJB Users List [EMAIL PROTECTED] Sent: Thursday, June 26, 2003 4:28 PM Subject: Re: SOLUTION for M:N never delete or always delete, no matter auto-delete=true or auto-delete=false hi edson, please have a look at the test case MtoNTest#testDeletionFromBothTables (auto-delete ON) and MtoNTest#testDeletionFromIntermediaryTable (auto-delete OFF). the first one fails because ojb only deletes from intermediary table. collection is not removal aware. jakob Edson Carlos Ericksson Richter wrote: (this is a real long mail, but I've made a long research. The first part is the reason I started to research, the second is explain why this occur. The third is a suggestion of how can we correct). FIRST PART: Ok. To avoid the problem related to OJB always using RemovalAwareCollection, I put my beans to work as public class A { private ArrayList myColl = new ArrayList(); public void setMyCollection( List collection ) { this.myColl.clear; this.myColl.addAll( collection ); } public List getMyCollection( ) {return this.myColl;} } Doing this, I'm converting from RemovalAwareCollection to ArrayList. Fine. Now suppose that I want auto-delete=true. Then I getMyCollection().remove(0); and then persist the object. Theorically, OJB should delete the object from indirection table AND the referenced table (the N side, ok?). This not occur. OJB deletes only from indirection table (the auto-delete option makes no difference). If I change the code to public class A { private List myColl; public void setMyCollection( List collection ) { this.myColl=collection; } public List getMyCollection( ) {return this.myColl;} } then it works (because the collection passed to setter is RemovalAwareCollection). BUT, if I put auto-delete=false, then OJB still delete the indirection table AND the referenced table (again, the auto-delete option makes no difference). SECOND PART: To the facts: since OJB is using RemovalAwareCollection, after the correct treatment for M:N non-decomposable queries (that my debugging show that it is working like a charm), the following code is being executed: // invoke callback on collection if (col instanceof ManageableCollection) { ((ManageableCollection) col).afterStore(this); } That is deleting the real objects, even if auto-delete=false. THIRD PART: The method deleteMtoNImplementor(...) should reset the allObjectsToBeRemoved in RemovalAwareCollection if the auto-delete option is set to false. What do you think? Something like create a RemovalAware interface. Make all classes (RemovalAwareCollection, and RemovalAwareList in my case) implement it. Then do public interface RemovalAware { public void resetDeleted(); } The resetDelete method implementation is just public void resetDeleted( ) { allObjectsToBeRemoved.clear(); } and then change PersistentBrokerImpl to currentMtoNKeys = getMtoNImplementor(cds, obj); // delete unused m:n implementors deleteMtoNImplementor(cds, obj, (Collection)col, currentMtoNKeys); if( col instanceof ManageableCollection !cds.getCascadeDelete() ) { Collection testCol; if( col instanceof CollectionProxy ) { testCol = ( ( CollectionProxy )col ).getData(); } else { testCol = ( Collection )col; } if( testCol instanceof RemovalAware ) { ( ( RemovalAware
Re: SOLUTION for M:N never delete or always delete, no matter auto-delete=true or auto-delete=false
Yes, Jakob gets the point. As far as I understood, if I don't specify the collection-class, OJB will use RemovalAwareCollection. Being as is, when I remove an object from the intermediary collection, the N object should be deleted from the N table when we store the M object only when auto-delete feature is true. If the collection-class is not RemovalAware, then there is no problem. Things should be as they had from months. Or OJB should not use RemovalAwareCollection as default for M:N non-decomposible. That's about my hack is. I undertand Thomas points about my configuration. He is right. Maybe the only thing that should be fixed is documentation. Maybe I'm doing some kind of biggest-than-ever mistake. Check what a kind of collection-descriptor I use here: collection-descriptor name=perfis element-class-ref=br.com.mgr.beans.PerfilPessoaFJBean indirection-table=RL_PESSOA_TIPOPESSOA proxy=true auto-retrieve=true auto-update=false auto-delete=false fk-pointing-to-this-class column=CO_PESSOA/ fk-pointing-to-element-class column=CO_TIPO_PESSOA/ /collection-descriptor where perfis is related to setPerfis and getPerfis: public class Pessoa { private List perfis; public void setPerfis( List p ) {this.perfis=p;} public List getPerfis( ) {return this.perfis;} } Just it! Now, if I delete an element as in getPerfis().remove(0) and then broker.store( pessoa ), the real object is not anymore deleted. And if I put auto-delete=true and issue getPerfis().remove(0) and then broker.store( pessoa ), the indirection record and the real object is deleted. May be this a my mis-interpretation? Why M:N documentation don't say anything about use ManageableArrayList if you wish your objects not being deleted from the N side? And that RemovalAwareCollection is the default collection if you don't specify one? Excuse-me if all this thread is my mistake, but I'm very happy because after fix tomorrow, all my app came to a stable and clear behaviour... Thanks, Edson Richter - Original Message - From: Jakob Braeuchi [EMAIL PROTECTED] To: OJB Users List [EMAIL PROTECTED] Sent: Thursday, June 26, 2003 5:27 PM Subject: Re: SOLUTION for M:N never delete or always delete, no matter auto-delete=true or auto-delete=false hi thomas, so my testcases are wrong as well :( (it's probably too hot here) to clarify this issue: - when the collection IS removal aware the n side is ALWAYS deleted when removed from the collection (not matter of the auto-xxx settings). - when the collection IS NOT removal aware the n side is NEVER deleted. is this how it should be ? jakob Thomas Mahler wrote: Hi again, Edson Carlos Ericksson Richter wrote: (this is a real long mail, but I've made a long research. The first part is the reason I started to research, the second is explain why this occur. The third is a suggestion of how can we correct). FIRST PART: Ok. To avoid the problem related to OJB always using RemovalAwareCollection, I put my beans to work as public class A { private ArrayList myColl = new ArrayList(); public void setMyCollection( List collection ) { this.myColl.clear; this.myColl.addAll( collection ); } public List getMyCollection( ) {return this.myColl;} } Doing this, I'm converting from RemovalAwareCollection to ArrayList. Fine. why do you type your attribute as ArrayList? if you just have List myColl = ... it would safe a lot of problems... If you really wnat to use ARrayList just use collection-class=ManageableArrayList in the collection-descriptor. This will avoid the addAll call! Now suppose that I want auto-delete=true. Then I getMyCollection().remove(0); and then persist the object. Theorically, OJB should delete the object from indirection table AND the referenced table (the N side, ok?). No! entries are deleted only from the indirection table! objects are only deleted automatically from the N side if you use a RemovalAwareCollection. This not occur. OJB deletes only from indirection table (the auto-delete option makes no difference). auto-delete does not change any behaviour of broker.store(...). It is meant to change behaviour of broker.delete(...) calls ! If I change the code to public class A { private List myColl; public void setMyCollection( List collection ) { this.myColl=collection; } public List getMyCollection( ) {return this.myColl;} } then it works (because the collection passed to setter is RemovalAwareCollection). as explained above. BUT, if I put auto-delete=false, then OJB still delete the indirection table AND the referenced table (again, the auto-delete option makes no difference). as expalined above. SECOND PART: To the facts: since OJB is using RemovalAwareCollection, after the correct treatment for M:N non-decomposable queries (that my debugging show that it is working like a charm), the following code