Well, I'm posting bellow the code I've used to create the virtual collection, and after a piece of code to query it (the use is obvious: I'll never read data/update data/delete data throught this collection. I just wanna this to be able to use it in Criteria when querying my database) :
PersistenceBroker b = null; try { b = getBroker(); ClassDescriptor cd = b.getClassDescriptor(MyMainClass.class); // That is the class where I want to query using the new collection. // It already exists on the repository.XML, but has no collection-descriptors CollectionDescriptor c = new CollectionDescriptor(cd); c.addAttribute("name", "myVirtualFieldName"); // This field doesn't exists in the bean. I'll just use it for queries. c.addAttribute("proxy", "true"); c.addAttribute("virtual", "true"); c.setCascadeDelete(false); c.setCascadeRetrieve(false); c.setCascadeStore(false); c.setCollectionClass(org.apache.ojb.broker.util.collections.ManageableArrayL ist.class); // I don't wanna nothing being deleted... c.setItemClass(TheCollectionClass.class); // that is a class that is already described in repository.XML, or it will never work c.setPersistentField(MyMainClass.class, "myVirtualFieldName"); c.addForeignKeyField("pkOnCollection"); // name of the field that is PK on the element collection cd.addCollectionDescriptor(c); after all, when I want to search for MyMainClass using an attribute of TheCollectionClass I just issue ... Criteria c = new Criteria(); c.addEqualTo("myVirtualFieldName", "02"); QueryByCriteria(MyMainClass.class, c, true); ... And OJB does the rest... The main problem I see is that when the virtual collection exists, OJB tries to set the primary key of the elements in the collection when storing (either update or insert) even when setCascade...(false), but the virtual field doesn't exists. So, to avoid this problem, and to not change behaviour of existing applications, I created the new attribute (virtual), so it will never be touch (when Insert or Update), when storing objects. If exists a better solution, or the behavior for storing objects will be fixed (it's not really broken, I just want to mean fixed in the way I work), we can work without the "virtual" solution ;) Thanks, Edson Richter ----- Original Message ----- From: Armin Waibel To: OJB Users List Sent: Wednesday, January 07, 2004 6:49 AM Subject: Re: Fwd: Using a non-existent collection inside a query Hi Edson, do you have a test case to show the problem? This would be helpful to test your "new feature" or to find another solution. regards, Armin Edson Carlos Ericksson Richter wrote: > (sorry, was a "momentary lapse of reason" when I clicked the send button). > > Hi! > > I'm facing a problem: I've a nice piece of sofware that load modules at > runtime. > Mostly, each module has their own .xml file with necessary configuration. > So, there are no problem here. > > But imagine that I've a customer_repository.xml, that references a quite > large table (let's say 100.000, to take easy to imagine). If each customer > has 1:n fone numbers, 1:n address, 1:documents, 1:n anything else, and so > on, I need to make use of the Proxies, or I'll crash server (or workstation) > memory (even with 512Mb). Ok, that's fine. But when I open my Swing UI, > every JTable, JList, JCombo and so on insists in materialize every 1:N > mapping in .XML file. So, I have a very large time when materializing > objects (to materialize one single person I take near 2 seconds... A user > "clicking away" in the machine think that this is a "long time" to wait for > a "simple navigation" in records! > > So I started to think in a solution where the collection is used when > mounting the WHERE clauses, but not when loading/writing objects to > database. And I started with API to create on-the-fly collections. > > All worked well, as I imagined (I can add the collection and play with > fine), but the first time I've attempted to write one customer object I get > that some method X was not found in object Y... And if I put the method X, I > get "column Z not in table" from my database. So, the OJB is trying to > persist the collection (even if I set the auto retrieve, auto update and > auto delete as false). Since I thinked in terms of virtual collection (that > can exists or not), and the queries and materialization are working fine, I > started to imagine the I need to make a patch to guarantee that the > collection will never be stored. Then, I've added a attribute "virtual" > that, when receives true, is ignored by "storeCollections" loop. > > My question is: can this be added to core OJB distribution, or I'll always > need to patch my own versions of OJB? > > The method was modified on PersistenceBrokerImpl is (just the > if(!"true".equals(cds.getAttribute("virtual"))) was added, and the > respective block start and end), and doesn't affect nobody else than who > wanna use these "virtual collection" way of work (I can send the code sample > where I'm using this, if you want): > > > private void storeCollections(Object obj, Vector vecCds) throws > PersistenceBrokerException > { > // get all members of obj that are collections and store all their elements > Iterator i = vecCds.iterator(); > while (i.hasNext()) > { > CollectionDescriptor cds = (CollectionDescriptor) i.next(); > if(!"true".equals(cds.getAttribute("virtual"))) { > Object col = cds.getPersistentField().get(obj); > Collection currentMtoNKeys = null; > if (col == null) > { > if (cds.isMtoNRelation()) > { > deleteMtoNImplementor(cds, obj); > } > } > else > { > // MBAIRD > // if the collection is a collectionproxy and it's not already loaded > // no need to store it. > if (col instanceof CollectionProxy && !((CollectionProxy) col).isLoaded()) > { > continue; > } > if (cds.isMtoNRelation()) > { > currentMtoNKeys = getMtoNImplementor(cds, obj); > // delete unused m:n implementors > deleteMtoNImplementor(cds, obj, (Collection)col, currentMtoNKeys); > } > Iterator colIterator; > if (col instanceof ManageableCollection) > { > colIterator = ((ManageableCollection) col).ojbIterator(); > } > else if (col instanceof Collection) > { > colIterator = ((Collection) col).iterator(); > } > else if (col.getClass().isArray()) > { > colIterator = new ArrayIterator(col); > } > else > { > throw new OJBRuntimeException( > col.getClass() > + " can not be managed by OJB, use Array, Collection or ManageableCollection > instead !"); > } > while (colIterator.hasNext()) > { > Object otherObj = colIterator.next(); > // for m:n mapped collections store association implementing entries > if (cds.isMtoNRelation()) > { > // 1. Store depended upon object first to avoid FK violation > storeCollectionObject(cds, otherObj); > // 2. Store indirection record > // BRJ: this could cause integrity problems because > // obj may not be stored depending on auto-update > storeMtoNImplementor(cds, obj, otherObj, currentMtoNKeys); > } > // for 1:n mapped collection assert proper fk assignment > else > { > if (cds.getCascadeStore()) > { > // BRJ: do not assign fk if not required > // to avoid materialization of proxy > assertFkAssignment(otherObj, obj, cds); > } > storeCollectionObject(cds, otherObj); > } > } > // invoke callback on collection > if (col instanceof ManageableCollection) > { > ((ManageableCollection) col).afterStore(this); > } > } > } > } > } > > > > > > --- > Outgoing mail is certified Virus Free. > Checked by AVG anti-virus system (http://www.grisoft.com). > Version: 6.0.554 / Virus Database: 346 - Release Date: 20/12/2003 --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.558 / Virus Database: 350 - Release Date: 2/1/2004 --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]