You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by Joerg Heinicke <jo...@gmx.de> on 2004/04/22 17:12:11 UTC

Re: [OTM] bug with most simple use case - the story goes on :)

Joerg Heinicke <joerg.heinicke <at> gmx.de> writes:

> Hello,
> 
> I have found another bug in OJB OTM when doing long transactions. What's
> strange about it is that it is probably the most simple use case.

Today I did the first update on OJB after Oleg's refactoring of OTM. Everything
seems to work so far except the use case mentioned below - this one is even
worse than before.

The reason is simple and seems to be due to the refactoring:
In the test case below in the method updateAddresses() the elements in
newAddresses and in oldAddresses are no longer the same and so the test
contains() returns always false, every element is deleted. This could probably
fixed by implementing equals() and hashcode() correctly.

But in theory the current situation (without having implemented equals() and
hashcode() correctly) should result in a complete delete of all elements in
oldAddresses and complete readd of all elements in newAddresses, shouldn't it?

At least it does not. The elements that have been equal before the refactoring,
but are now deleted - because they are no longer equal in the sense of equals()
- are *not* readded when calling makePersistent() on them as it is done with the
second loop iterating over newAddresses. So in every iteration all already
existing addresses are lost and only newly added addresses live - up to the next
iteration only again!

The test case below is somewhat insufficient for the new error as it tests only
correct updates, but not existence of the address at all:

>     public void testSomethingSimple() throws Throwable {

...

>         addresses = this.getAddresses();

// this additional check is missing
assertEquals("Collection of addresses must be 1. ", 1, addresses.size());

>         iter = addresses.iterator();
>         while (iter.hasNext()) {

BTW, did this test case made it into the CVS? I searched it, but could not find
it.

Thanks for any effort fixing it finally :)

Joerg

> The symptom: I can create and delete persistent objects, but I can not update
> them. First I retrieve the objects via getCollectionByQuery(). Later I iterate
> over the old Collection and call deletePersistent() for no longer existing
> objects, and iterate over the new Collection and call makePersistent() for new
> and updated objects.
> 
> When doing remote debugging I see that the objects have the correct values
> immediately before makePersistent() - and after it. But no update on the
> database is done (through profileSql=true for MySQL I can see the fired SQL
> statements). Even the next call to getCollectionByQuery() returns the objects
> with the correct values that are not in the database though a SELECT on the
> database is done.
> 
> Please find the test case below. If you remove the conn.invalidateAll() you
> will see the expected behaviour, no error is reported. But when not getting
> the objects from the cache you see that no update was done.
> 
> Thanks in advance,
> 
> Joerg

gmane.org complains about "There's much more quoted text in your article than
new. Prune quoted stuff.", so I only link to the test case:
http://marc.theaimsgroup.com/?l=ojb-dev&m=107996623210592&w=4


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


double references to one object (was: [OTM] bug with most simple use case)

Posted by Joerg Heinicke <jo...@gmx.de>.
On 18.05.2004 21:20, Oleg Nitz wrote:

>>the test !newAddresses.contains(oldAddress) always returns false. OJB
>>handles it internally so that no db access will be done if not
>>necessary, i.e. if the "same" elements (in OJB sense, but different in
>>Java sense) will be readded in the same tx.
>>
>>But the behaviour is a bit strange. Is this by
>>intention/design/implementation?
> 
> All of the above :)
> Very simple: object identity uniquely identifies the object. 
> AFAIK Sun JDO spec also treats object identity in similar way,
> which differs from the way of standard Java APIs.

Ok, sounds logical :)

I found today another buggy behaviour, but have not look deeply enough 
into it, what more or less means I have no test case until now.
Just to give the idea: I have a legalcase and a depending collection of 
events (as history). Some of those events have again a depending 
collection of objects (here: payment by installment, installment rates). 
As long as the event collection is valid (here: no other event occured 
changing the payment method) the collection is also referenced on the 
legalcase directly. But if the payment method changes the collection on 
the legalcase will be set to null. Unfortunately a 
makePersistent(legalcase) does not cut the reference from each 
installment rate to the legalcase. After a server restart the legalcase 
object will be restored with the installment rates collection though it 
was set to null before.

installment rate table:
id | period | amount | eventId | legalcaseId
  1 |     30 |    100 |       1 |           1
  2 |     60 |    100 |       1 |           1
  3 |     90 |    100 |       1 |           1

After setting installment rate collection to null on the legalcase and 
makePersistent() the legalcaseId should be 0.

IIRC I already had a similar issue some time ago. At that time I removed 
this double reference as it was more disturbing than helpful from the 
application POV, but here it is more than just helpful. Is this 
requirement to pretentiously?

Joerg

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [OTM] bug with most simple use case - the story goes on :)

Posted by Oleg Nitz <on...@ukr.net>.
Hi Joerg,

On Monday 17 May 2004 22:49, Joerg Heinicke wrote:
> the test !newAddresses.contains(oldAddress) always returns false. OJB
> handles it internally so that no db access will be done if not
> necessary, i.e. if the "same" elements (in OJB sense, but different in
> Java sense) will be readded in the same tx.
>
> But the behaviour is a bit strange. Is this by
> intention/design/implementation?
All of the above :)
Very simple: object identity uniquely identifies the object. 
AFAIK Sun JDO spec also treats object identity in similar way,
which differs from the way of standard Java APIs.

Regards,
  Oleg


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [OTM] bug with most simple use case - the story goes on :)

Posted by Joerg Heinicke <jo...@gmx.de>.
On 15.05.2004 22:11, Oleg Nitz wrote:

> Hi Jeorg,
> 
> It's fixed. Insert after delete didn't change the state of object, so it was 
> deleted.

Thanks for the fix, it works. Just curious about another consequence of 
the code refactoring: I wrote in this thread:

"The reason for the non-working of the code in contrary to the March 
code is that in updateAddresses() the items in the collection 
newAddresses and oldAddresses are different, the equals() or here 
contains() does no longer work."

Due to this change in

private Collection updateAddresses(Collection newAddresses) {
// massively shortened
     Collection oldAddresses = _conn.getCollectionByQuery(q);
     Iterator oldAddressesIterator = oldAddresses.iterator();

     while (oldAddressesIterator.hasNext()) {
         Address oldAddress = (Address)oldAddressesIterator.next();
         if (!newAddresses.contains(oldAddress)) {
             _conn.deletePersistent(oldAddress);
         }
     }

the test !newAddresses.contains(oldAddress) always returns false. OJB 
handles it internally so that no db access will be done if not 
necessary, i.e. if the "same" elements (in OJB sense, but different in 
Java sense) will be readded in the same tx.

But the behaviour is a bit strange. Is this by 
intention/design/implementation?

Thanks again for the fix in time for the customer presentation tomorrow ;-)

Joerg

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [OTM] bug with most simple use case - the story goes on :)

Posted by Oleg Nitz <on...@ukr.net>.
Hi Jeorg,

It's fixed. Insert after delete didn't change the state of object, so it was 
deleted.

Regards,
 Oleg

On Saturday 15 May 2004 01:44, Joerg Heinicke wrote:
> On 14.05.2004 00:30, Oleg Nitz wrote:
> > Hi Jeorg,
> >
> > Sorry for doing nothing about OTM problems last time, I'll try to start
> > doing more.
>
> No problem. I made it work for me doing the two iterations in two
> transactions, though this can obviously lead to data loss.
>
> I only found it strange that there was no reaction at all.
>
> >>BTW, did this test case made it into the CVS? I searched it, but could
> >> not find it.
> >
> > It's here: SwizzleTests.testSomethingSimple()
> > Can you give me the diff, please?
>
> Oh, don't know why I did not find it. The test diff is extremely easy.
>
> Joerg
>
>
> Index: SwizzleTests.java
> ===================================================================
> RCS file:
> /home/cvspublic/db-ojb/src/test/org/apache/ojb/otm/SwizzleTests.java,v
> retrieving revision 1.13
> diff -u -r1.13 SwizzleTests.java
> --- SwizzleTests.java	12 Apr 2004 16:32:42 -0000	1.13
> +++ SwizzleTests.java	14 May 2004 22:41:26 -0000
> @@ -475,6 +475,8 @@
>           addresses = this.updateAddresses(addresses);
>           addresses = this.getAddresses();
>
> +        assertEquals("Collection of addresses must be 1. ", 1,
> addresses.size());
> +
>           iter = addresses.iterator();
>           while (iter.hasNext()) {
>               Address address = (Address)iter.next();
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [OTM] bug with most simple use case - the story goes on :)

Posted by Joerg Heinicke <jo...@gmx.de>.
On 14.05.2004 00:30, Oleg Nitz wrote:

> Hi Jeorg,
> 
> Sorry for doing nothing about OTM problems last time, I'll try to start doing 
> more.

No problem. I made it work for me doing the two iterations in two 
transactions, though this can obviously lead to data loss.

I only found it strange that there was no reaction at all.

>>BTW, did this test case made it into the CVS? I searched it, but could not
>>find it.
> 
> It's here: SwizzleTests.testSomethingSimple()
> Can you give me the diff, please?

Oh, don't know why I did not find it. The test diff is extremely easy.

Joerg


Index: SwizzleTests.java
===================================================================
RCS file: 
/home/cvspublic/db-ojb/src/test/org/apache/ojb/otm/SwizzleTests.java,v
retrieving revision 1.13
diff -u -r1.13 SwizzleTests.java
--- SwizzleTests.java	12 Apr 2004 16:32:42 -0000	1.13
+++ SwizzleTests.java	14 May 2004 22:41:26 -0000
@@ -475,6 +475,8 @@
          addresses = this.updateAddresses(addresses);
          addresses = this.getAddresses();

+        assertEquals("Collection of addresses must be 1. ", 1, 
addresses.size());
+
          iter = addresses.iterator();
          while (iter.hasNext()) {
              Address address = (Address)iter.next();

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Re: [OTM] bug with most simple use case - the story goes on :)

Posted by Oleg Nitz <on...@ukr.net>.
Hi Jeorg,

Sorry for doing nothing about OTM problems last time, I'll try to start doing 
more.

On Thursday 22 April 2004 18:12, Joerg Heinicke wrote:
> BTW, did this test case made it into the CVS? I searched it, but could not
> find it.
It's here: SwizzleTests.testSomethingSimple()
Can you give me the diff, please?

Thank you for your patience,
 Oleg


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org