google-code-export / objectify-appengine

Automatically exported from code.google.com/p/objectify-appengine
MIT License
1 stars 0 forks source link

NullPointerException in PolymorphicEntityMetadata.getConcrete #80

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Insert entity with Long id
2. Delete entity
3. Attempt to find deleted entity using Long id

What is the expected output? What do you see instead?
Expected output is null from find

What version of the product are you using? On what operating system?
objectify-3.0b2

Please provide any additional information below.
I just upgraded from 2.2.3 to 3.0b2 for polymorphic persistence support.  

My model is analogous to the class Animal, Dog, Cat, kind of pattern.  In this 
model Animal has the @Entity annotation, and Dog and Cat have @Subclass 
annotations.  My Animal, Dog and Cat classes have @Cached annotations as well.

I have a unit test that inserts a "Cat", stores the generated id, deletes the 
Cat, and then attempts to verify that it cannot find the original Cat (using 
the stored id).  

The code sequence is basically this:
Key<Cat> key = ofy().put(cat);
ofy().delete(cat);
assert ofy().find(Cat.class,cat)==null;

When I run this unit test, I get the stack trace below (slighty modified to 
change my test class name).

The line with the NPE is this one:
String discriminator = (String)ent.getProperty(DISCRIMINATOR_PROPERTY);

I'm trying to put together a standalone unit test, but I thought I'd post this 
in the interim.

Here's the stack trace.

java.lang.RuntimeException: java.lang.NullPointerException
    at com.googlecode.objectify.cache.CachingAsyncDatastoreService$5.run(CachingAsyncDatastoreService.java:385)
    at com.googlecode.objectify.cache.ListenableFuture.isDone(ListenableFuture.java:76)
    at com.googlecode.objectify.cache.ListenableFuture.get(ListenableFuture.java:92)
    at com.googlecode.objectify.cache.MergeFuture.get(MergeFuture.java:81)
    at com.googlecode.objectify.cache.MergeFuture.get(MergeFuture.java:17)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:67)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:67)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:67)
    at com.googlecode.objectify.impl.ResultAdapter.get(ResultAdapter.java:29)
    at com.googlecode.objectify.impl.ObjectifyImpl.find(ObjectifyImpl.java:108)
    at mycompany.gae.dao.impl.EntityDaoGaeImpl.find(EntityDaoGaeImpl.java:46)
    at mycompany.gae.dao.UserDaoTest.getUserWithId(UserDaoTest.java:74)
    at mycompany.gae.dao.UserDaoTest.createReadUpdateDelete(UserDaoTest.java:61)
    at mycompany.gae.dao.UserDaoTest.testUserDaoCrud(UserDaoTest.java:80)
    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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NullPointerException
    at com.googlecode.objectify.impl.PolymorphicEntityMetadata.getConcrete(PolymorphicEntityMetadata.java:135)
    at com.googlecode.objectify.impl.PolymorphicEntityMetadata.getCached(PolymorphicEntityMetadata.java:163)
    at com.googlecode.objectify.cache.CachingAsyncDatastoreService.categorize(CachingAsyncDatastoreService.java:86)
    at com.googlecode.objectify.cache.CachingAsyncDatastoreService.putInCache(CachingAsyncDatastoreService.java:191)
    at com.googlecode.objectify.cache.CachingAsyncDatastoreService$5.run(CachingAsyncDatastoreService.java:380)
    ... 54 more

Original issue reported on code.google.com by greg.ara...@gmail.com on 11 Apr 2011 at 12:18

GoogleCodeExporter commented 9 years ago
Oops..

assert ofy().find(Cat.class,cat)==null;

should have been:
assert ofy().find(Cat.class,key)==null;

Original comment by greg.ara...@gmail.com on 11 Apr 2011 at 12:23

GoogleCodeExporter commented 9 years ago
Found and reproduced in a test.  Thanks!

Original comment by lhori...@gmail.com on 11 Apr 2011 at 2:42

GoogleCodeExporter commented 9 years ago
Fixed.  One consequence is that cache misses use the @Cached behavior of the 
root of an entity hierarchy.  The reason is that saying ofy.find(Cat.class, 
123) is really no different than saying ofy.find(Animal.class, 123) - since 
there is no backing entity there is no discriminator to determine caching 
behavior.

It's either this or disallow @Cached on @Subclasses, always using the @Entity 
cache behavior.  This seems to make more sense, but I'm up for debate.

Original comment by lhori...@gmail.com on 11 Apr 2011 at 3:34

GoogleCodeExporter commented 9 years ago
Thank YOU for all your hard work, and for sharing it with us. Looking forward 
to 3.0 final :-)

Original comment by greg.ara...@gmail.com on 11 Apr 2011 at 4:09