views:

1510

answers:

2

AppEngine 1.2.2. I define a class Product like so:

@PersistenceCapable(identityType = IdentityType.APPLICATION, table="Products")
public class Product {

 public Product(String title) {
  super();
  this.title = title;
 }

 public String getTitle() {
  return title;
 }

 @Persistent
 String title;

 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 private Key id;
}

I define a derived class Book like so:

@PersistenceCapable(identityType = IdentityType.APPLICATION, table="Products")
public class Book extends Product {

 public Book(String author, String title) {
  super(title);
  this.author = author;
 }

 public String getAuthor() {
  return author;
 }

 @Persistent
 String author;
}

I then make a new object like so:

PersistenceManager pm = PMF.get().getPersistenceManager(); pm.makePersistent(new Book("George Orwell", "1984"));

I can query for this new object using a query like:

Query query = pm.newQuery("select from " + Book.class.getName() + " where author == param"); query.declareParameters("String param"); List results = (List) query.execute("George Orwell");

This returns the object, because I am querying a field 'author' defined on Book.

However this doesn't work:

Query query = pm.newQuery("select from " + Book.class.getName() + " where title == param"); query.declareParameters("String param"); List results = (List) query.execute("1984");

It throws an exception which states there is no field 'title', even through this is defined on the derived class Product.

javax.jdo.JDOUserException: Field "title" does not exist in com.example.Book or is not persistent
NestedThrowables:
org.datanucleus.store.exceptions.NoSuchPersistentFieldException: Field "title" does not exist in com.example.Book or is not persistent

It seems as if fields from inherited classes are not available in the Datastore queries.

Is this in fact possible with a variation on the syntax, or with annotations?

+1  A: 

That query, using DataNucleus with any of the other datastores we support (e.g RDBMS, XML, Excel, etc), should indeed allow fields in superclasses; the query is valid JDOQL. If they don't work in GAE/J then report the issue in Google's issue tracker, though there is certainly an issue there about inheritance already http://code.google.com/p/datanucleus-appengine/issues/list

DataNucleus
+3  A: 

from: http://code.google.com/appengine/docs/java/datastore/usingjdo.html

Unsupported Features of JDO

The following features of the JDO interface are not supported by the App Engine implementation:

Unowned relationships. You can implement unowned relationships using explicit Key values. JDO's syntax for unowned relationships may be supported in a future release. Owned many-to-many relationships.

"Join" queries. You cannot use a field of a child entity in a filter when performing a query on the parent kind. Note that you can test the parent's relationship field directly in query using a key.

JDOQL grouping and other aggregate queries.

Polymorphic queries. You cannot perform a query of a class to get instances of a subclass. Each class is represented by a separate entity kind in the datastore.

IdentityType.DATASTORE for the @PersistenceCapable annotation. Only IdentityType.APPLICATION is supported.

There is currently a bug preventing preventing persistent fields on superclasses from being saved to the datastore. This will be fixed in a future release.

Gaurav