0

I'm trying to figure out why this code is throwing NPE:

@RequestMapping(value = "/share/{id}/store/{typeId}", method = RequestMethod.PUT)
public ResponseEntity<Share> updateShareStore(@PathVariable final long id,
                                         @PathVariable final String typeId) {
    EntityManagerFactory emf = EMF.get();
    EntityManager em = emf.createEntityManager();
    Share share = null;
    logger.debug(User.class.getName());
    try {
        share = em.find(Share.class, id);
        Store store = em.find(Store.class, typeId);
        share.getStores().add(store);
        em.merge(share);
    } finally {
        em.close(); // NPE Here!
    } 
    return new ResponseEntity<Share>(share,HttpStatus.OK);
}

Error:

java.lang.NullPointerException 
    at com.google.appengine.datanucleus.StoreFieldManager.processPersistable(StoreFieldManager.java:453)
    at com.google.appengine.datanucleus.StoreFieldManager.getDatastoreObjectForCollection(StoreFieldManager.java:987)
    at com.google.appengine.datanucleus.StoreFieldManager.storeRelations(StoreFieldManager.java:877)
    at com.google.appengine.datanucleus.DatastorePersistenceHandler.updateObject(DatastorePersistenceHandler.java:426)
    at org.datanucleus.state.JDOStateManager.flush(JDOStateManager.java:3832)
    at org.datanucleus.ObjectManagerImpl.flushInternalWithOrdering(ObjectManagerImpl.java:3884)
    at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:3807)
    at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:3747)
    at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:4137)
    at org.datanucleus.ObjectManagerImpl.transactionPreCommit(ObjectManagerImpl.java:428)
    at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:400)
    at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:288)
    at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:1090)
    at org.datanucleus.api.jpa.JPAEntityManager.close(JPAEntityManager.java:193)
    at org.demo.resources.ShareController.updateShare(ShareController.java:83)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)

Could it be because that I use em with two Object types? But it's unlikely that way.

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
quarks
  • 33,478
  • 73
  • 290
  • 513
  • Try to print a log after **em.merge(share);** statement because may be the entitymanager gets closed somewhere in the try block itself or even before that. Also, you should have a NPE check before closing _any_ resources. – Gurminder Singh Jun 10 '14 at 07:09
  • 1
    what is the code at `StoreFieldManager.java:453` – Scary Wombat Jun 10 '14 at 07:10
  • 1
    The stacktrace does not contain a frame with `updateShareStore` method. Either it is wrong stacktrace or the code you posted has nothing to do with the exception. – Oleg Estekhin Jun 10 '14 at 07:38
  • 1
    It seems, that "store" variable is null. When em.close() is invoked, the transaction is being commit. But reference of "share" to null can not be saved to DB. That is why you get NPE. You have to check, whether "store" is not null and only then invoke share.getStores().add(store); – nazlo Jun 10 '14 at 08:50

0 Answers0