ludoch / datanucleus-appengine

Automatically exported from code.google.com/p/datanucleus-appengine
0 stars 0 forks source link

Unexpected UnsupportedOperationException when calling getObjectById() #203

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I'm getting a random Exception coming from 
org.datanucleus.store.appengine.EntityUtils

The piece of code where the exception happens is :
public static String getPropertyName(
      IdentifierFactory idFactory, AbstractMemberMetaData ammd) {
    // TODO(maxr): See if there is a better way than field name comparison to
    // determine if this is a version field
    AbstractClassMetaData acmd = ammd.getAbstractClassMetaData();
    if (acmd.hasVersionStrategy() &&
        ammd.getName().equals(acmd.getVersionMetaData().getFieldName())) {
      return getVersionPropertyName(idFactory, acmd.getVersionMetaData());
    }

    // If a column name was explicitly provided, use that as the property name.
    if (ammd.getColumn() != null) {
      return ammd.getColumn();
    }

    // If we're dealing with embeddables, the column name override
    // will show up as part of the column meta data.
    if (ammd.getColumnMetaData() != null && ammd.getColumnMetaData().length
> 0) {
      if (ammd.getColumnMetaData().length != 1) {
        // TODO(maxr) throw something more appropriate
        throw new UnsupportedOperationException();
      }
      return ammd.getColumnMetaData()[0].getName();
    }
    // Use the IdentifierFactory to convert from the name of the field into
    // a property name.
    return
idFactory.newDatastoreFieldIdentifier(ammd.getName()).getIdentifierName();
  }

I'm not sure if this is a bug on datanuclus-appengine or on my code, but I
don't know how could I posibly make the AbstractMemberMetaData have two
columns (which is what it has)?

Any idea?

Original issue reported on code.google.com by opsi...@gmail.com on 15 Apr 2010 at 12:41

GoogleCodeExporter commented 8 years ago
Stack trace:
java.lang.UnsupportedOperationException
    at org.datanucleus.store.appengine.EntityUtils.getPropertyName(EntityUtils.java:62)
    at
org.datanucleus.store.appengine.DatastoreFieldManager.getPropertyName(DatastoreF
ieldManager.java:1073)
    at
org.datanucleus.store.appengine.DatastoreFieldManager.fetchObjectField(Datastore
FieldManager.java:309)
    at
org.datanucleus.state.AbstractStateManager.replacingObjectField(AbstractStateMan
ager.java:1197)
    at org.ugr.rtpstat.server.orm.UsuarioRegistrado.jdoReplaceField(UsuarioRegistrado.java)
    at org.ugr.rtpstat.server.orm.UsuarioRegistrado.jdoReplaceFields(UsuarioRegistrado.java)
    at
org.datanucleus.state.JDOStateManagerImpl.replaceFields(JDOStateManagerImpl.java
:2772)
    at
org.datanucleus.state.JDOStateManagerImpl.replaceFields(JDOStateManagerImpl.java
:2791)
    at
org.datanucleus.store.appengine.DatastorePersistenceHandler.fetchObject(Datastor
ePersistenceHandler.java:466)
    at org.datanucleus.state.JDOStateManagerImpl.validate(JDOStateManagerImpl.java:4263)
    at org.datanucleus.ObjectManagerImpl.findObject(ObjectManagerImpl.java:2444)
    at
org.datanucleus.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.ja
va:1671)
    at
org.datanucleus.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.ja
va:1767)
    at
org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManager.getObjectById
(DatastoreJDOPersistenceManager.java:73)
    at
org.ugr.rtpstat.server.RtpstatServiceImpl.getRegisteredUser(RtpstatServiceImpl.j
ava:86)
    at
org.ugr.rtpstat.server.RtpstatServiceImpl.getRegisteredUser(RtpstatServiceImpl.j
ava:78)
    at org.ugr.rtpstat.server.RtpstatServiceImpl.getUserName(RtpstatServiceImpl.java:191)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100)
    at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:562)
    at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceSer
vlet.java:188)
    at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceSer
vlet.java:224)
    at
com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemot
eServiceServlet.java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.jav
a:1166)
    at
com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.
java:51)
    at
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.jav
a:1157)
    at
com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(Transactio
nCleanupFilter.java:43)
    at
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.jav
a:1157)
    at
com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilte
r.java:122)
    at
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.jav
a:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at
com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineW
ebAppContext.java:70)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at
com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.han
dle(JettyContainerService.java:349)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

Original comment by opsi...@gmail.com on 15 Apr 2010 at 6:34

GoogleCodeExporter commented 8 years ago
I am seeing this in appengine 1.3.4 running development server:

     [java] java.lang.UnsupportedOperationException
     [java]     at
org.datanucleus.store.appengine.EntityUtils.getPropertyName(EntityUtils.java:62)
     [java]     at
org.datanucleus.store.appengine.DatastoreFieldManager.storeObjectField(Datastore
FieldManager.java:839)
     [java]     at
org.datanucleus.store.appengine.DatastoreFieldManager.storeStringField(Datastore
FieldManager.java:474)
     [java]     at
org.datanucleus.state.AbstractStateManager.providedStringField(AbstractStateMana
ger.java:1023)
     [java]     at com.mvranalytics.decider.model.Account.jdoProvideField(Account.java)
     [java]     at
com.mvranalytics.decider.model.AbstractPersistent.jdoProvideFields(AbstractPersi
stent.java)
     [java]     at
org.datanucleus.state.JDOStateManagerImpl.provideFields(JDOStateManagerImpl.java
:2715)
     [java]     at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPreProcess(Dat
astorePersistenceHandler.java:341)
     [java]     at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(Datast
orePersistenceHandler.java:251)
     [java]     at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(Datasto
rePersistenceHandler.java:240)
     [java]     at
org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManager
Impl.java:3185)
     [java]     at
org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManagerImpl.jav
a:3161)
     [java]     at
org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1
298)
     [java]     at
org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:1175)
     [java]     at
org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManage
r.java:669)
     [java]     at
org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.j
ava:694)
     [java]     at org.springframework.orm.jdo.JdoTemplate$9.doInJdo(JdoTemplate.java:334)
     [java]     at org.springframework.orm.jdo.JdoTemplate.execute(JdoTemplate.java:205)
     [java]     at
org.springframework.orm.jdo.JdoTemplate.makePersistent(JdoTemplate.java:332)

Original comment by archie.c...@gmail.com on 20 May 2010 at 8:55

GoogleCodeExporter commented 8 years ago
I forgot to mention it, but going back to Java 1.5 solved this problem for me.

Original comment by opsi...@gmail.com on 20 May 2010 at 10:05

GoogleCodeExporter commented 8 years ago
Is this the same bug that was supposedly fixed in:
http://code.google.com/p/datanucleus-appengine/issues/detail?id=63

?

Original comment by catc...@gmail.com on 13 Jun 2010 at 10:00

GoogleCodeExporter commented 8 years ago
@catchwa I don't think that's the same issue as that was closed around eight 
months before this one was reported

Original comment by opsi...@gmail.com on 13 Jun 2010 at 10:06

GoogleCodeExporter commented 8 years ago
I am also getting , some time ok, when I run on debug mode it is running , 

running on SDK version 1.3.4  and JDK 1.6 

Original comment by comla...@gmail.com on 18 Jun 2010 at 6:33

GoogleCodeExporter commented 8 years ago
I replaced this code (where pm is an instance of the PersistanceManager):

User u = pm.getObjectById(User.class, targetKey);

with

User u;
Query query = pm.newQuery(User.class);
query.setFilter("key == targetKey");
query.declareParameters("String targetKey");
List<User> results = (List<User>) query.execute(targetKey);
if(results.size() != 0)
{
  u = results.get(0);
}

And I don't get this error any more.

Which kind of sucks because it's less efficient (because I'm searching based on 
a key, which is either going to return 1 or no hits)

Original comment by catc...@gmail.com on 19 Jun 2010 at 12:35

GoogleCodeExporter commented 8 years ago
I think as well that this is a race condition: when it occurs for me, 
ammd.getColumnMetaData() contains two times the same information (for a @Basic 
SortedSet<String>).

I have a workaround that seems to work: at start up I force loading datanucleus 
metada by querying for an entity (no matter if one is found or not). Then, when 
my tasks run in parallel, initialisation has already been done and the problem 
doesn't appear any more.

Original comment by mguille...@yahoo.fr on 9 Nov 2010 at 10:29

GoogleCodeExporter commented 8 years ago
In my case putting getObjectById() in a synchronized method helped.

Original comment by kamil.ci...@gmail.com on 1 Dec 2010 at 7:06

GoogleCodeExporter commented 8 years ago
I'm getting lots of these errors in production if I enable threadsafe for my 
app. I get it for writes (PersistenceManager.makePersistant) and for reads 
(PersistenceManager.getObjectById). Disabling threadsafe helps (no errors at 
all), but with upcoming pricing it would be nice to be able to use threadsafe 
mode.

Original comment by juha.kos...@gmail.com on 13 May 2011 at 3:51

GoogleCodeExporter commented 8 years ago
Has anyone tried adding:

<property name="javax.jdo.option.Multithreaded" value="true"/>

to jdoconfig.xml ?

Original comment by m...@wikiwebserver.org on 18 May 2011 at 8:12

GoogleCodeExporter commented 8 years ago
I added 

<property name="javax.jdo.option.Multithreaded" value="true"/> 

to jdoconfig.xml and I have not seen this issue occur in the last 24 hours.

Fingers crossed this is the solution.

Original comment by goo...@jads.co.uk on 19 May 2011 at 3:02

GoogleCodeExporter commented 8 years ago
After about 30 hours I've got the same error again.

Original comment by ya...@yatul.com on 21 May 2011 at 7:13

GoogleCodeExporter commented 8 years ago
Yeah, me too. And this time the instance threw nothing but exceptions until I 
switched default versions to force it offline. I'm just thankful I noticed it.

I hate solving race conditions like this! Especially when they not in my code! 

I'm trying something else now. The exception seems to happen shortly after a 
new instance starts. I think if two or more requests are handled by the new 
instance concurrently there is a race condition in this "setting up period" 
when the metadata is processed.

So, I'm encouraging this to happen synchronously. This is my PMF which I hope 
will set things up safely before handling concurrent requests:

public final class PMF {

    private static final PersistenceManagerFactory pmfInstance = 
        JDOHelper.getPersistenceManagerFactory("transactions-optional");

    static {

        // JDO setup does not appear to be thread-safe and will break an instance
        // if called concurrently at startup when fetching metadata.
        // To fix this, ensure metadata is fetched only once.
        // TODO Remove this hack and find cleaner solution

        Class[] entityClasses = { Licence.class, Statistic.class };

        PersistenceManager pm = getPersistenceManager();
        try {
            for (Class c : entityClasses) {           
                try {
                    // Triggers entity class metadata to be loaded
                    // Does not matter if id 0 does not exist.
                    pm.getObjectById(c, 0);
                }
                catch (Exception ignored) { }
            }
        }
        finally {
            pm.close();
        }
    }

    public static synchronized PersistenceManager getPersistenceManager() {
        return pmfInstance.getPersistenceManager();
    }
}

Original comment by goo...@jads.co.uk on 21 May 2011 at 9:48

GoogleCodeExporter commented 8 years ago
Nope, that failed to help. I just had 2 hours of downtime because of a corrupt 
instance.

Looks like it is impossible to use JPA/JDO on app engine with 
<thread-safe>true</thread-safe>

Hopefully this will be resolved before the new billing comes into effect.

Original comment by goo...@jads.co.uk on 22 May 2011 at 1:58

GoogleCodeExporter commented 8 years ago
Please try whatever you're doing with SVN trunk code. This uses DataNucleus v3.x

Original comment by googleco...@yahoo.co.uk on 18 Jul 2011 at 9:47

GoogleCodeExporter commented 8 years ago

Original comment by googleco...@yahoo.co.uk on 21 Sep 2011 at 3:50

GoogleCodeExporter commented 8 years ago
A customer has reproduced the problem with SVN trunk code. I'll see if I can 
put together a reproducible test case.

Original comment by max.r...@gmail.com on 29 Nov 2011 at 9:41

GoogleCodeExporter commented 8 years ago
A customer provided a reproducible testcase that allowed me to reproduce the 
issue. I've made a jar with the fix available at 
http://code.google.com/p/datanucleus-appengine/downloads/detail?name=datanucleus
-appengine-1.0.10.1.jar

Please replace datanucleus-appengine-1.0.10.jar in your project with this jar, 
give it a try, and let me know if it helps.

Thanks,
Max

Original comment by max.r...@gmail.com on 10 Dec 2011 at 2:02

GoogleCodeExporter commented 8 years ago
Marking as fixed as of 1.0.10.

Original comment by max.r...@gmail.com on 20 Jan 2012 at 8:48

GoogleCodeExporter commented 8 years ago
I see that datanucleus-appengine-1.0.10.final.jar is still in the 1.6.1.1 of 
AppEngine.  Is there a plan to replace it with your fixed jar 
(datanucleus-appengine-1.0.10.1.jar) in a future release?

Original comment by aaron.sh...@onfast.com on 20 Jan 2012 at 8:56

GoogleCodeExporter commented 8 years ago
No, the next version that gets bundled with the SDK will be version 2.0 of the 
plugin, which is currently available as a separate download for this project. 
It won't be in the next SDK (due out in January) but it should be in the one 
that follows.

Original comment by max.r...@gmail.com on 20 Jan 2012 at 11:21