You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by Joose Vettenranta <jo...@iki.fi> on 2007/05/17 15:07:24 UTC

problem with collection

Hello,

I'm trying to update my class but it does not remove removed items  
from the collection. So, when I add new items to the collection, in  
DB there are copies of those old instances. So, when restarting  
application, it fetches too many instances (old ones and new ones).

May 17 15:50:33 kanta1 postgres[17491]: [113-1] LOG:  statement:  
SELECT 1
May 17 15:50:33 kanta1 postgres[17491]: [114-1] LOG:  statement:  
UPDATE ibiz_invoices SET global_id=397,client='xxxx
....
May 17 15:50:33 kanta1 postgres[17491]: [114-7]   
12345-67890',order_description='',payment_terms=35,notification_time=8,i 
nterest='9.500',notification_payment='10.00' WHERE id =
May 17 15:50:33 kanta1 postgres[17491]: [114-8]  39
May 17 15:50:33 kanta1 postgres[17491]: [115-1] LOG:  statement:  
commit;begin;

This only happens if I have first created the original object and  
then tried to update it. So if I restart my application and try this  
again to same object, then it removes references.

code:

dao.begin();
ibizobj.setId(id);
ibizobj=dao.retrieve(ibizobj);
col = ibizobj.getOrderItems();
// col == java.util.Collection
print (col.size()); // outputs 5
col.clear();
print (col.size()); // outputs 0
dao.update(ibizobj);
//nothing is deleted from db

dao-code:

dao.update == broker.store(bean, ObjectModificationDefaultImpl.UPDATE);

repository:

<class-descriptor class="com.intertechnika.ibiz.invoices.Invoice"  
table="ibiz_invoices">
...
  <collection-descriptor name="orderItems" auto-retrieve="true" auto- 
delete="true" auto-update="true"
			element-class-ref="com.intertechnika.ibiz.invoices.InvoiceItem">
   <inverse-foreignkey field-ref="invoice_id"/>
</class-descriptor>
<class-descriptor class="com.intertechnika.ibiz.invoices.InvoiceItem"  
table="ibiz_invoice_items">
...
  <field-descriptor name="invoice_id"	column="invoice_id"	jdbc- 
type="INTEGER" access="anonymous" />
  <reference-descriptor name="invoice" class- 
ref="com.intertechnika.ibiz.invoices.Invoice" auto-retrieve="true"  
auto-update="false" auto-delete="false">
    <foreignkey field-ref="invoice_id" />
  </reference-descriptor>
</class-descriptor>

Only thing that seems to work is to do it like this:
dao.begin();
ibizobj.setId(id);
ibizobj=dao.retrieve(ibizobj);
col = ibizobj.getOrderItems();
// col == java.util.Collection
//PSEUDO CODE STARS HERE
foreach orderItem do dao.remove(orderItem);
//PSEUDO CODE ENDS HERE
dao.update(ibizobj);
//nothing is deleted from db

Using ojb 1.0.1 and java 1.4.2

I tried to look from release notes that if this is a bug that is  
fixed, but did not find anything.

Thanks,

Joose Vettenranta



Re: problem with collection

Posted by Alessandro Colantoni <al...@gmail.com>.
Hi Joose.
I think that the behavior of ojb is right, or at least I always accepted it
as right.
When you update an object that hold a collection, new object in the
collection will be stored (if autoupdate = true in repository.xml), but the
objects you delete from collection will not be deleted from database. The
autodelete = true means that if you delete the main object, the object in
the collection will be deleted too, and it doesn't mean that if you update
the main object, object not yet present in the collection be removed form
database.
Now that you know that it's not so hard to write a method that acts as you
want, update objects of the collection that still are in it, inserting the
new ones, and deleting form database the removed ones.
I had the same needing so, I have the method, if you want you can try it (it
works fine).
I have two method:

updateCollectionReference(Object storeVO, String pAttributeName)

Updates the object storeVO and all objects of the collection associated to
pAttributeName.
pAttributeName  has to be the name of a collection properties.
 It deletes all objects in the database not present in the collection
specified by pAttributeName
 Connection management and transaction management are fully delegated.</br>
 User must no care at all!!.

 updateCollectionReferences(Object storeVO)
Act as updateCollectionReference(Object storeVO, String pAttributeName) with
the difference that it has done for all references

Of course don't forget to put autoupdate = true

If you want use them you have to download my library (mandragora) at
http://mandragora.sourceforge.net/
Mandragora is a collection of useful methods built on Ojb apis

If you want just steal the code of the methods, you can find them in the
class it.aco.mandragora.bd.standard.StandardManagerBD

I hope this can help
greetings
Alessandro Colantoni


On 5/17/07, Joose Vettenranta <jo...@iki.fi> wrote:
>
> Hello,
>
> I'm trying to update my class but it does not remove removed items
> from the collection. So, when I add new items to the collection, in
> DB there are copies of those old instances. So, when restarting
> application, it fetches too many instances (old ones and new ones).
>
> May 17 15:50:33 kanta1 postgres[17491]: [113-1] LOG:  statement:
> SELECT 1
> May 17 15:50:33 kanta1 postgres[17491]: [114-1] LOG:  statement:
> UPDATE ibiz_invoices SET global_id=397,client='xxxx
> ....
> May 17 15:50:33 kanta1 postgres[17491]: [114-7]
> 12345-67890',order_description='',payment_terms=35,notification_time=8,i
> nterest='9.500',notification_payment='10.00' WHERE id =
> May 17 15:50:33 kanta1 postgres[17491]: [114-8]  39
> May 17 15:50:33 kanta1 postgres[17491]: [115-1] LOG:  statement:
> commit;begin;
>
> This only happens if I have first created the original object and
> then tried to update it. So if I restart my application and try this
> again to same object, then it removes references.
>
> code:
>
> dao.begin();
> ibizobj.setId(id);
> ibizobj=dao.retrieve(ibizobj);
> col = ibizobj.getOrderItems();
> // col == java.util.Collection
> print (col.size()); // outputs 5
> col.clear();
> print (col.size()); // outputs 0
> dao.update (ibizobj);
> //nothing is deleted from db
>
> dao-code:
>
> dao.update == broker.store(bean, ObjectModificationDefaultImpl.UPDATE);
>
> repository:
>
> <class-descriptor class="com.intertechnika.ibiz.invoices.Invoice "
> table="ibiz_invoices">
> ...
> <collection-descriptor name="orderItems" auto-retrieve="true" auto-
> delete="true" auto-update="true"
>                        element-class-ref="
> com.intertechnika.ibiz.invoices.InvoiceItem">
>   <inverse-foreignkey field-ref="invoice_id"/>
> </class-descriptor>
> <class-descriptor class="com.intertechnika.ibiz.invoices.InvoiceItem "
> table="ibiz_invoice_items">
> ...
> <field-descriptor name="invoice_id"   column="invoice_id"     jdbc-
> type="INTEGER" access="anonymous" />
> <reference-descriptor name="invoice" class-
> ref="com.intertechnika.ibiz.invoices.Invoice" auto-retrieve="true"
> auto-update="false" auto-delete="false">
>    <foreignkey field-ref="invoice_id" />
> </reference-descriptor>
> </class-descriptor>
>
> Only thing that seems to work is to do it like this:
> dao.begin();
> ibizobj.setId(id);
> ibizobj=dao.retrieve(ibizobj);
> col = ibizobj.getOrderItems ();
> // col == java.util.Collection
> //PSEUDO CODE STARS HERE
> foreach orderItem do dao.remove(orderItem);
> //PSEUDO CODE ENDS HERE
> dao.update(ibizobj);
> //nothing is deleted from db
>
> Using ojb 1.0.1 and java 1.4.2
>
> I tried to look from release notes that if this is a bug that is
> fixed, but did not find anything.
>
> Thanks,
>
> Joose Vettenranta
>
>
>