Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OneToOne: Null Pointer Exception on Save() or Update() in GAE #11

Open
OuchMyHead opened this issue Nov 8, 2011 · 1 comment
Open

Comments

@OuchMyHead
Copy link

This bug occured using Siena 2.0.5 and GAE-1.4 within the Play! Framework 1.2.3

If an Owner object is persisted without being associated with a Child object, then the Owner object can never be associated with any Child. When we try to associate a Child with a Parent object then a null pointer exception is thrown on save() and update().

You can use the following code to reproduce this error:

**** Owner Model ****


public class OwnerModel extends Model {

    @Id(Generator.AUTO_INCREMENT)
    public Long id;

    @Owned(mappedBy="owner")
    public One<ChildModel> child;

}

**** Child Model ****


public class ChildModel {

    @Id(Generator.AUTO_INCREMENT)
    public Long id;

    public OwnerModel owner;

}

**** Test Code ****


public void OneToOneTest(){
        OwnerModel owner = new OwnerModel();
        owner.save();

        ChildModel child = new ChildModel();
        owner.child.set( child );
        owner.save();       //null pointer exception thrown here
    }

As demonstrated above, the null pointer exception is thrown when making the second save() call. The error will also be thrown when calling update() on the Owner model - however, an error is NOT thrown when using insert() as the second call as this creates a new, additional Owner model and associates the Child with the new Owner.

The Stacktrace is as follows:

java.lang.NullPointerException
    at siena.gae.GaePersistenceManager.save(GaePersistenceManager.java:2206)
    at siena.gae.GaePersistenceManager._updateManageMaps(GaePersistenceManager.java:846)
    at siena.gae.GaePersistenceManager._updateComplex(GaePersistenceManager.java:611)
    at siena.gae.GaePersistenceManager.update(GaePersistenceManager.java:516)
    at siena.gae.GaePersistenceManager.save(GaePersistenceManager.java:898)
    at siena.Model.save(Model.java:87)
    at UserTests.UserTest.OneToOneTest(UserTest.java:456)
    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.RunAfters.evaluate(RunAfters.java:31)
    at play.test.PlayJUnitRunner$StartPlay$2$1.evaluate(PlayJUnitRunner.java:98)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    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 play.test.PlayJUnitRunner.run(PlayJUnitRunner.java:48)
    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.runner.JUnitCore.run(JUnitCore.java:157)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
    at play.test.TestEngine.run(TestEngine.java:101)
    at controllers.TestRunner.run(TestRunner.java:67)
    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 play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:546)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:500)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:476)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:471)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:159)
    at play.server.PlayHandler$NettyInvocation.execute(PlayHandler.java:220)
    at play.Invoker$Invocation.run(Invoker.java:265)
    at play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:200)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
@OuchMyHead
Copy link
Author

It appears that if we make the set the OneToOne relationship within an Owner object to NULL at any point, then this bug also occurs when trying to associate a Child at a later date.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant