Question

I am trying to put a kind of entities in the same entity group than its parent. I have read some post here but no one seems to have the same problem so I have to be doing something wrong (but I am not able to see it) .

I got Brands (father) and Stores (sons), my issue is when trying to add an Store to a Brand where, for some reason, I am getting a weird NullPointerException.

Caused by: java.lang.NullPointerException
    at com.google.appengine.datanucleus.scostore.FKListStore$3.fetchFields(FKListStore.java:1093)
...

Here are the classes involved and the code adding the Store to the father:

@PersistenceCapable
public class Brand {

   @PrimaryKey
   @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
   @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
   protected String key;

    @Persistent
    @Extension(vendorName="datanucleus", key="gae.pk-id", value="true")
    protected Long keyId;

   @Persistent(defaultFetchGroup = "false")
   private List<Store> stores;
}

And this is the Store:

@PersistenceCapable
public class Store {
   @PrimaryKey
   @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
   @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
   protected String key;

   @Persistent
   @Extension(vendorName="datanucleus", key="gae.pk-id", value="true")
   private Long keyId;

   @Persistent(mappedBy = "stores") 
   protected BrandEntity brand;

}

A Brand has been created at some point and now I want to add an Store to the same entity group. Nothing strange:

public static StoreEntity addStore(String brandKey, Store store) {
   PersistenceManager mgr = getPersistenceManager();
   try { 
      BrandEntity brand = mgr.getObjectById(BrandEntity.class, brandKey);

      if (brand != null){
          brand.getStores(); //feth to retrieve collection from datastore           

          //add relationship
          newStore.setBrand(brand);
          List<StoreEntity> aux = brand.getStores(); //list is lazily fetched here
          if (aux == null)
             aux = new ArrayList<Store>();  //maybe is the first one ()            

          /*-- Nullpointer next line --*/
          aux.add(newStore);
          /*--NullPointer last line --*/

          brand.setStores(aux); 
          brand = mgr.makePersistent(brand);
          return store;
      }
   } finally{
      mgr.close();
   }

   return null;
}

I am aware that at the appengine documentation example the "mappedBy="nameOf theField" is at the parent (Brand in my case) instead of putting it at the son (Store) but I want the Store to be at the same Entity group than Brand.

So, if anyone has any suggestion I will really apreciate it.

Was it helpful?

Solution 2

Thanks to @Danaucleus for solving my issue. My mistake was just that I was setting the BrandEntity as parent of the Store manually.

store.addBrand(theBrand); //this should not be done
brand.getStores().add(store);

but this parent relationship is automatically filled when doing this:

brand.getStores().add(store);

Also, as I wanted a bidirectional relationship, I have to put the "mappedBy" annotation on both sides of the relationship, this at BrandEntity class (parent):

@Persistent (mappedBy="brand")
private List<StoreEntity> stores;

This at StoreEntity class (child)

@persistent (mappedBy="stores"
BrandEntity brand;

So I was definitively missing something stupid but it is true that the NullPointerException I was getting was unclear and unhelpful.

OTHER TIPS

"mappedBy" is at the wrong end, see JDO spec and http://www.datanucleus.org/products/accessplatform_3_3/jdo/orm/one_to_many_list.html#fk_bi and a 1-N bidirectional relation should go between "Store" and "Brand", so no idea what "BrandEntity" has to do with this.

PS. the problem is in Google's plugin (as shown by the com.google package naming), not DataNucleus.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top