DataNucleus JIRA is now in read-only mode. Raise any new issues in GitHub against the plugin that it applies to.
DataNucleus JIRA will remain for the foreseeable future but will eventually be discontinued

Actual situation:
We have two persistence capable classes: MyClass1 and MyClass2.
MyClass1 has a LinkedList of MyClass2 called myClass2Collection.
Both classes have a String called 'identifierString'.
MyClass2 has in addition a String called identifierStringMyClass1 in which the identifierString of MyClass1 is also stored away.
MyClass2 overrides equals so identifierString has to be equal.

Now we make some objects of MyClass1 and MyClass2 persistent with the constraint
that are at least two or more objects in the database with the same identifierString of MyClass1 and MyClass2.
Now we load MyClass2 with identifierString for example 'MyClass2-1-1'.
On the basis of myClass2.identifierStringMyClass1 we load the corresponding Object of MyClass1.
Now we want to check, if the collection myClass2Collection in the Object of MyClass1 contains the object of MyClass2 with the identifier "MyClass2-1-1".

So we call if(myClass1.getMyClass2Collection().contains(myClass2))
or if(myClass1.getMyClass2Collection().indexOf(myClass2) != -1)

Now we get different results if we switch datanucleus.cache.collection and datanucleus.cache.collection.lazy.
Here are the results:
1. datanucleus.cache.collection = false and datanucleus.cache.collection.lazy = false -> contains and indexOf return false
2. datanucleus.cache.collection = true and datanucleus.cache.collection.lazy = false -> contains and indexOf return true
3. datanucleus.cache.collection = true and datanucleus.cache.collection.lazy = true -> contains returns false and indexOf returns true
It seems that in case 1. and 3. the overridden equals-Method are not called.
Only case 2. makes the correct call to the overridden equals-Method of MyClass2.

Description

Actual situation:
We have two persistence capable classes: MyClass1 and MyClass2.
MyClass1 has a LinkedList of MyClass2 called myClass2Collection.
Both classes have a String called 'identifierString'.
MyClass2 has in addition a String called identifierStringMyClass1 in which the identifierString of MyClass1 is also stored away.
MyClass2 overrides equals so identifierString has to be equal.
Now we make some objects of MyClass1 and MyClass2 persistent with the constraint
that are at least two or more objects in the database with the same identifierString of MyClass1 and MyClass2.
Now we load MyClass2 with identifierString for example 'MyClass2-1-1'.
On the basis of myClass2.identifierStringMyClass1 we load the corresponding Object of MyClass1.
Now we want to check, if the collection myClass2Collection in the Object of MyClass1 contains the object of MyClass2 with the identifier "MyClass2-1-1".
So we call if(myClass1.getMyClass2Collection().contains(myClass2))
or if(myClass1.getMyClass2Collection().indexOf(myClass2) != -1)
Now we get different results if we switch datanucleus.cache.collection and datanucleus.cache.collection.lazy.
Here are the results:
1. datanucleus.cache.collection = false and datanucleus.cache.collection.lazy = false -> contains and indexOf return false
2. datanucleus.cache.collection = true and datanucleus.cache.collection.lazy = false -> contains and indexOf return true
3. datanucleus.cache.collection = true and datanucleus.cache.collection.lazy = true -> contains returns false and indexOf returns true
It seems that in case 1. and 3. the overridden equals-Method are not called.
Only case 2. makes the correct call to the overridden equals-Method of MyClass2.

Hardly "strange", since no overridden methods can be called if the operation is evaluated in the datastore. Pull all objects into memory, and then call the operation if you want your methods to be called.

Maybe some other mode of control of the backing store could be added so the user chooses what happens, but there are always compromises, and if you want to use overridden equals/hashCode then you can never have a field with a "large" collection (since you want to avoid loading it all up in-memory)

Andy Jefferson added a comment - 18/Aug/11 10:38 AM Hardly "strange", since no overridden methods can be called if the operation is evaluated in the datastore. Pull all objects into memory, and then call the operation if you want your methods to be called.
Maybe some other mode of control of the backing store could be added so the user chooses what happens, but there are always compromises, and if you want to use overridden equals/hashCode then you can never have a field with a "large" collection (since you want to avoid loading it all up in-memory)

Andy Jefferson added a comment - 13/Oct/11 12:54 PM Really the same idea as NUCCORE-543, to do with caching and when operations are evaluated in the datastore, consequently anything to look at these will be done together; moving testcase to NUCCORE-543