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 com.google.appengine.api.memcache.MemcacheSerialization.serialize(MemcacheSerialization.java:262)
at com.google.appengine.api.memcache.MemcacheSerialization.makePbKey(MemcacheSerialization.java:199)
at com.google.appengine.api.memcache.MemcacheServiceImpl.get(MemcacheServiceImpl.java:274)
at com.google.appengine.api.memcache.stdimpl.GCache.remove(GCache.java:175)
at org.datanucleus.cache.javaxcache.JavaxCacheLevel2Cache.evict(JavaxCacheLevel2Cache.java:192)
at org.datanucleus.ObjectManagerImpl.performLevel2CacheUpdateAtCommit(ObjectManagerImpl.java:2982)
at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:2925)
at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:369)
at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:256)
at org.datanucleus.jpa.EntityTransactionImpl.commit(EntityTransactionImpl.java:104)
at org.datanucleus.store.appengine.jpa.DatastoreEntityTransactionImpl.commit(DatastoreEntityTransactionImpl.java:55)

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 com.google.appengine.api.memcache.MemcacheSerialization.serialize(MemcacheSerialization.java:262)
at com.google.appengine.api.memcache.MemcacheSerialization.makePbKey(MemcacheSerialization.java:199)
at com.google.appengine.api.memcache.MemcacheServiceImpl.get(MemcacheServiceImpl.java:274)
at com.google.appengine.api.memcache.stdimpl.GCache.remove(GCache.java:175)
at org.datanucleus.cache.javaxcache.JavaxCacheLevel2Cache.evict(JavaxCacheLevel2Cache.java:192)
at org.datanucleus.ObjectManagerImpl.performLevel2CacheUpdateAtCommit(ObjectManagerImpl.java:2982)
at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:2925)
at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:369)
at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:256)
at org.datanucleus.jpa.EntityTransactionImpl.commit(EntityTransactionImpl.java:104)
at org.datanucleus.store.appengine.jpa.DatastoreEntityTransactionImpl.commit(DatastoreEntityTransactionImpl.java:55)
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 = txCachedIter.next();
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())
{
NucleusLogger.CACHE.debug(LOCALISER.msg("004014",
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?)

/**
* 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)

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.remove(oldID);
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?

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

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.

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: java.io.NotSerializableException: org.datanucleus.state.JDOStateManager
...

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: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.