2013-03-05 23 views
7

'u kullanarak varlık eklerken Nullpointerexception, otomatik olarak oluşturulmuş uç nokta sınıfını kullanmam konusunda kafam karıştı. Veri deposuna yeni nesne eklemek için oluşturulan son nokta kullanmak istiyorum. Ancak, bir istisna atıyor.Otomatik oluşturulan Classendpoint ekleme yöntemi

fooEndpoint.insertFoo(foo); // throws null pointer exception 

Benim varlık sınıfı bu kaynakta verilen örnekle benzer:

java.lang.NullPointerException 
at org.datanucleus.api.jpa.JPAEntityManager.find(JPAEntityManager.java:318) 
at org.datanucleus.api.jpa.JPAEntityManager.find(JPAEntityManager.java:256) 
at com.FooEndpoint.containsFoo(FooEndpoint.java:150) 
at com.FooEndpoint.insertFoo(FooEndpoint.java:96) 

: Burada

@Entity 
public class Foo { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Key ID; 

Yığın izleme: Burada https://developers.google.com/appengine/docs/java/datastore/jpa/overview.

benim varlıktır Diğer taraftan, EntityManager kalıcı yöntemini kullandığımda yeni nesne ekleyebilirim. Çünkü bu, veri deposunda mevcut olup olmadığını kontrol etmez.

Bunu, classEndpoint ekleme yönteminin nesneyi kaydetmesi ve kimliğe otomatik anahtarını almasını beklemesini beklerim. Veya ID alanını başlatmam gerekiyor.

İşte otomatik oluşturulan uç nokta sınıfı insertFoo yöntemi.

/** 
* This inserts a new entity into App Engine datastore. If the entity already 
* exists in the datastore, an exception is thrown. 
* It uses HTTP POST method. 
* 
* @param foo the entity to be inserted. 
* @return The inserted entity. 
*/ 
public Foo insertFoo(Foo foo) { 
    EntityManager mgr = getEntityManager(); 
    try { 
     if (containsFoo(foo)) { 
      throw new EntityExistsException("Object already exists"); 
     } 
     mgr.persist(foo); 
    } finally { 
     mgr.close(); 
    } 
    return foo; 
} 

Burada containsFoo yöntemi

private boolean containsFoo(Foo foo) { 
    EntityManager mgr = getEntityManager(); 
    boolean contains = true; 
    try { 
     Foo item = mgr.find(Foo.class, foo.getID()); // exception occurs here 
     if (item == null) { 
      contains = false; 
     } 
    } finally { 
     mgr.close(); 
    } 
    return contains; 
} 

foo.getID() boş olduğunu. Çünkü bu yeni bir nesnedir. Bunu bekliyorum, uygulama motoru bunun için bir anahtar oluşturur. Veya bunun için açıkça bir anahtar oluşturmam gerekiyor mu?

Foo sınıfındaki diğer alanlar, String ve booleans gibi basit türlerdir.

Zaman ayırdığınız için teşekkür ederiz.

+1

"insertFoo" yönteminin kaynağını sağlayabilir misiniz? Ne foo olarak geçiyorsun? –

+0

Bulut son nokta üreteci ekleme yönteminin eski sürümünün yeni sürümden farklı olduğunu anlıyorum. Çünkü, eski sürümde ekleme yöntemi, varlık kontrolü olmadan nesneyi kalıcı hale getirir (yöntem içerir). Ancak, yeni olanlar nesnenin varlığını kontrol eder. Ancak, anahtar boşsa, bir istisna atıyor. Lütfen, bu durum normal mi değil mi? – retto

cevap

8

Tam olarak aynı sorunla karşılaştım. Çalıştığım şekilde sunacağım.

Orijinal otomatik olarak oluşturulan Uç noktalar sınıfı ilgili kodu:

private boolean containsFoo(Foo foo) { 
    EntityManager mgr = getEntityManager(); 
    boolean contains = true; 
    try { 
     Foo item = mgr.find(Foo.class, foo.getID()); 
     if (item == null) { 
      contains = false; 
     } 
    } finally { 
     mgr.close(); 
    } 
    return contains; 
} 

bir bağımsız değişken olarak geçirilir işletme nesnesi için bir boş bir kontrol dahil ilgili kod değiştirildi.

private boolean containsFoo(Foo foo) { 
    EntityManager mgr = getEntityManager(); 
    boolean contains = true; 
    try { 
     // If no ID was set, the entity doesn't exist yet. 
     if(foo.getID() == null) 
      return false; 
     Foo item = mgr.find(Foo.class, foo.getID()); 
     if (item == null) { 
      contains = false; 
     } 
    } finally { 
     mgr.close(); 
    } 
    return contains; 
} 

Bu şekilde, daha deneyimli yanıtların ve açıklamaların görüneceğinden emin olmama rağmen varsayılan olarak çalışacaktır.

+0

includesFoo yöntemi, asıl soru bağlamında boş bir ID alır ve kilitlenir, veri deposunun bu öğeyi içerip içermediğini anlayamasa bile, Entity Manager'ın find() yöntemini kullanır. Sorum şu: eğer yeni varlıklar bir kimliğe sahip değilse, geçerli bir kimlik gerektiren varlıklar için nasıl kontrol edilebilirler? – igordcard

2

Bulut bitiş noktalarını otomatikleştirmek için Eclipse Eklentisi'ni kullandıktan sonra aynı sorunu yaşıyordum ("Google> Bulut Son Nokta Sınıfı Oluştur" seçeneğini belirleyerek). tavsiyen ardından

, ben ekledi:

if (foo.getID() == null) // return false kendi nesnenin adıyla foo değiştirin;

Sorun çözüldü.

Bu, Google'ın otomatik olarak oluşturulmuş kodu nasıl güncellemedi, çünkü bu son derece yinelenen bir sorun olmalı?

Çözüm için teşekkürler.

İlgili konular