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
Issue Details (XML | Word | Printable)

Key: NUCCORE-540
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Andy Jefferson
Reporter: Andy Jefferson
Votes: 0
Watchers: 3

If you were logged in you would be able to see more operations.
DataNucleus Core

ObjectManager currently attempts to cache objects that have no identity (embedded) causing attempted serialisation

Created: 03/Jun/10 08:11 AM   Updated: 08/Jan/15 08:35 AM   Resolved: 03/Jun/10 08:18 AM
Component/s: Cache
Affects Version/s: 2.0.4, 2.1.0.m1, 2.1.0.m2, 2.1.0.m3
Fix Version/s: 2.1.0.release

 Description  « Hide
No identity means don't even try to cache

Sort Order: Ascending order - Click to sort in descending order
Andy Jefferson added a comment - 03/Jun/10 08:18 AM
SVN trunk fixes this

Ales Justin added a comment - 16/Aug/10 03:12 PM
I've applied the NUCCONRE-540 to 1.1.5 branch (revision 7070),
but I still get the error:

java.lang.IllegalArgumentException: can't accept class org.datanucleus.identity.IdentityReference as a memcache entity
at org.datanucleus.cache.javaxcache.JavaxCacheLevel2Cache.evict(
at org.datanucleus.ObjectManagerImpl.performLevel2CacheUpdateAtCommit(
at org.datanucleus.ObjectManagerImpl.preCommit(
at org.datanucleus.TransactionImpl.internalPreCommit(
at org.datanucleus.TransactionImpl.commit(
at org.datanucleus.jpa.EntityTransactionImpl.commit(

As you can see it actually doesn't go into newly added code:

    private void performLevel2CacheUpdateAtCommit()
        // Lock the L2 cache so nobody else can have it while we are updating objects
        // Without this we can get race conditions between threads taking objects out, and
        // us putting objects in leading to assorted exceptions in AbstractStateManager or
        // in the PC object jdoReplaceField() methods.
        Level2Cache l2Cache = omf.getLevel2Cache();
        synchronized (l2Cache)
            // Process all modified objects adding/updating/removing from L2 cache as appropriate
            Iterator txCachedIter = txCachedIds.iterator();
            while (txCachedIter.hasNext())
                Object id =;
                StateManager sm = enlistedSMCache.get(id);
                if (sm == null)
                    // Modified object no longer enlisted so has been GCed, so remove from L2
                    if (NucleusLogger.CACHE.isDebugEnabled())
                            id, String.valueOf(l2Cache.getSize())));
                    l2Cache.evict(id); // <-- HERE

What would be the proper way to fix this?
(e.g. do we actually really need the NUCCORE-539?)

Ales Justin added a comment - 16/Aug/10 03:44 PM
Ah, let me just mention what I'm actually doing -- which is pretty simple.

EntityManager em = ...;
// begin its transaction
FooBar entity = new FooBar();
// commit or rollback

Yup, plain simple save.
Should this "// Modified object no longer enlisted so has been GCed, so remove from L2" really apply here?

Ales Justin added a comment - 17/Aug/10 02:04 PM
From this code

            Iterator txCachedIter = txCachedIds.iterator();
            while (txCachedIter.hasNext())
                Object id =;
                System.err.println("-------> " + id);
                StateManager sm = enlistedSMCache.get(id);

this is the id

id = {org.datanucleus.identity.IdentityReference@4423}
key: javax.jdo.identity.LongIdentity = {javax.jdo.identity.LongIdentity@4604}"2"

whereas the key is the only key in "enlistedSMCache" map.
If this is of any help ...

Ales Justin added a comment - 17/Aug/10 02:14 PM
The ids get replaced

     * Replace the previous object id for a persistable object with a new one.
     * This is used where we have already added the object to the cache(s) and/or enlisted it in the txn before
     * its real identity was fixed (attributed in the datastore).
     * @param pc The Persistable object
     * @param oldID the old id it was known by
     * @param newID the new id
    public synchronized void replaceObjectId(Object pc, Object oldID, Object newID)

        if (enlistedSMCache.get(oldID) != null)
            // Swap the enlisted object identity
            if (sm != null)
                enlistedSMCache.put(newID, sm);

but the one in the txCached remains the same -- hence no match.

Was this already fixed in some other JIRA issue?

Andy Jefferson added a comment - 19/Sep/10 08:25 PM
1.1 isn't supported. If you have some issue reproducible with 2.x then please attach a testcase

Ales Justin added a comment - 20/Sep/10 03:31 PM
Does some 2.x already work on AppEngine?

Andy Jefferson added a comment - 20/Sep/10 03:42 PM
Not that I'm aware of. AppEngine plugin is the responsibility of Google and not received communication from them on that plugin in some time (sadly); I got tired of asking when they planned on supporting 2.x a long time ago

Ales Justin added a comment - 20/Sep/10 03:56 PM
>> I got tired of asking when they planned on supporting 2.x a long time ago

Any idea what might be different from 1.x to 2.x wrt the issue?
Since afai looked, things look pretty much similar.

I can try to produce a simple test, since reproducing this is trivial: simple save/persist + use javax.cache impl with Serializable keys as a must.

Anton Kosyakov added a comment - 08/Apr/12 03:03 PM

I reproduced this bug on datanucleus 3.0.6.

I've upgraded appengine v.1.6.4 to datanucleus-appengine v2 and added datanucleus-cache-3.0.3.jar in war/WEB-INF/lib directory to enable "javax.cache" (GAE Memcache).

But when I tried to persist entity I got the following error:
java.lang.IllegalArgumentException: Cannot use as a key: 'org.datanucleus.identity.IdentityReference@7d27a2b6'
Caused by: org.datanucleus.state.JDOStateManager

Andy Jefferson added a comment - 08/Apr/12 05:33 PM
Hi, maybe you did but then that is not latest code, and you provide no testcase so consequently unreproduceable

Pawel Szpyt added a comment - 08/Jan/15 12:07 AM
It is still a problem in 3.1.3, which is the latest code compatible with Google app engine as far as I know. I have @PersistenceCapable class X with property Y that is @PersistenceCapable @EmbeddedOnly. Everything was working fine, I wanted to use cache, so I added @Cacheable to my class X, added the apropriate cache jar and the entries to jdoconfig.xml (datanucleus.cache.level2.type = jcache, datanucleus.cache.level2.cacheName = whatever) and now I get exactly what Anton Kosyakov got. 2.1.0.release did not fix this bug, and at least 3.0.6 and 3.1.3 are still affected.

Pawel Szpyt added a comment - 08/Jan/15 12:09 AM
I forgot to add: I get this error while commiting a JDO transaction (in the transaction I change the instance of class X).

Andy Jefferson added a comment - 08/Jan/15 08:35 AM
THIS issue is closed.
If you have some (other) problem then kindly follow the problem reporting guide at By that we mean you provide a testcase that follows those templates to DEMONSTRATE something.