My favorites | Sign in
Project Home Downloads Wiki Issues Source
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 25: Support inheritance
122 people starred this issue and may be notified of changes. Back to list
Status:  Verified
Owner:  max.r...@gmail.com
Closed:  Nov 2009


Sign in to add a comment
 
Project Member Reported by max.r...@gmail.com, Apr 13, 2009
  @PersistenceCapable(identityType = IdentityType.APPLICATION)
  public class Top {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;

    @Persistent public String topVal;
  }

  @PersistenceCapable(identityType = IdentityType.APPLICATION)
  public class Middle extends Top {

    @Persistent public String middleVal;
  }

  @PersistenceCapable(identityType = IdentityType.APPLICATION)
  public class Bottom extends Middle {

    @Persistent public String bottomVal;
  }


 [org.datanucleus.store.appengine.DatastoreProperty@394563d4,
org.datanucleus.store.appengine.DatastoreProperty@7a9d10ab]
org.datanucleus.exceptions.NucleusUserException: Cannot find mapping for
field org.datanucleus.test.Sander$Top.id in table <class name="Sander$Middle"
       identity-type="application"
       objectid-class="javax.jdo.identity.LongIdentity"
       persistence-modifier="persistence-capable"
>
<inheritance strategy="superclass-table">
</inheritance>
<field name="middleVal"
       persistence-modifier="persistent"
       null-value="none"
       default-fetch-group="true"
       embedded="true"
       unique="false">
<column name="middleVal"/>
</field>
</class>
 [org.datanucleus.store.appengine.DatastoreProperty@394563d4,
org.datanucleus.store.appengine.DatastoreProperty@7a9d10ab]
	at
org.datanucleus.store.appengine.DatastoreTable.addApplicationIdUsingClassTableId(DatastoreTable.java:696)
	at
org.datanucleus.store.appengine.DatastoreTable.initializePK(DatastoreTable.java:587)
	at
org.datanucleus.store.appengine.DatastoreTable.buildMapping(DatastoreTable.java:272)
	at
org.datanucleus.store.appengine.DatastoreManager.newStoreData(DatastoreManager.java:252)
	at
org.datanucleus.store.AbstractStoreManager.addClasses(AbstractStoreManager.java:720)
	at
org.datanucleus.store.AbstractStoreManager.addClass(AbstractStoreManager.java:691)
	at
org.datanucleus.store.mapped.MappedStoreManager.getDatastoreClass(MappedStoreManager.java:360)
	at
org.datanucleus.store.appengine.DatastoreManager.getDatastoreClass(DatastoreManager.java:471)
	at
org.datanucleus.store.appengine.DatastoreFieldManager.buildMappingConsumerForWrite(DatastoreFieldManager.java:924)
	at
org.datanucleus.store.appengine.DatastoreFieldManager.<init>(DatastoreFieldManager.java:134)
	at
org.datanucleus.store.appengine.DatastoreFieldManager.<init>(DatastoreFieldManager.java:165)
	at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:178)
	at
org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3067)
	at
org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManagerImpl.java:3043)
	at
org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1258)
	at
org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:1135)
	at
org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:668)
	at
org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:693)
Apr 13, 2009
Project Member #1 max.r...@gmail.com
(No comment was entered for this change.)
Labels: FoundIn-1.0.0
Jul 14, 2009
#2 ngovank...@gmail.com
I think this issue should be a high priority one. MVC and OOP are things we can't
live without them. But when we have them with the M (Model) just be in 2 level
inheritances, can we live? :-)

My work is depending on this issue.
Jul 21, 2009
#3 dominiqu...@gmail.com
The limitation to a depth of two makes us squeezing attributes in a small
hierarchies, introducing a lot of code duplication...

To me that's a big issue!

Possibilities to refactor the code in an Agile way is now very limited.

What can we do to help it being fixed?
Jul 23, 2009
Project Member #4 max.r...@gmail.com
(No comment was entered for this change.)
Labels: -Priority-Medium Priority-High
Jul 28, 2009
Project Member #5 max.r...@gmail.com
(No comment was entered for this change.)
Summary: Support inheritance
Jul 28, 2009
Project Member #6 max.r...@gmail.com
 Issue 71  has been merged into this issue.
Jul 28, 2009
Project Member #7 max.r...@gmail.com
 Issue 66  has been merged into this issue.
Aug 2, 2009
Project Member #8 max.r...@gmail.com
 Issue 52  has been merged into this issue.
Aug 2, 2009
Project Member #9 max.r...@gmail.com
 Issue 34  has been merged into this issue.
Aug 11, 2009
Project Member #10 max.r...@gmail.com
 Issue 112  has been merged into this issue.
Aug 18, 2009
Project Member #11 max.r...@gmail.com
This will be the first thing I work on for 1.0.4.  It may be the only thing I work on
for 1.0.4....
Labels: -Priority-High Priority-Critical TargetRelease-1.0.4
Aug 18, 2009
#12 lystoc...@gmail.com
Will there be also inheritance support for JPA?
Aug 18, 2009
Project Member #13 max.r...@gmail.com
Yes, this issue will not be resolved until there is inheritance support for both JDO
and JPA.
Sep 7, 2009
Project Member #14 max.r...@gmail.com
(No comment was entered for this change.)
Status: Started
Sep 26, 2009
Project Member #15 max.r...@gmail.com
 Issue 137  has been merged into this issue.
Oct 6, 2009
#16 dominiqu...@gmail.com
I would like some clarifications ;)

- My development liberty already is limited because I cannot define a class hierarchy
deeper than 2 levels.
- These last days, I'm trying to deal with the  issue 112 : Cannot query fields of
object's inherited classes! Max merged the  issue 112  with this one.

To me the situation is worth: even if the issue about the hierarchy depth limited to
2 is remove, it seems the impossibility to query inherited attributes will still
limit the depth to ONE!

I would like to have some insurance about the fact that the fix for 25 will also fix
the  issue 112 ... Any ETA? At least a little hint about the fix delivery before me
having to flatten my class hierarchy? ;)

A+, Dom
Oct 7, 2009
Project Member #17 max.r...@gmail.com
When this issue is resolved you'll be able to have an inheritance hierarchy deeper
than 2 and you'll be able to filter and sort using inherited attributes.  In short,
you should be able to do all the things you would expect to be able to do.

I'm working on all of this now.  It's not going to be done for the next SDK (1.2.6,
due out shortly) but it will be done for the SDK after (1.2.7).  I will probably make
a preview release available so that early adopters can try it out against 1.2.6. 
Oct 16, 2009
#18 dominiqu...@gmail.com
Thanks Max for the update. You were right: 1.2.6 is just out! I've marked my code for
the corresponding refactoring. With the delivery of your fix, it will be lightweight
and much more efficient.
Oct 22, 2009
Project Member #19 max.r...@gmail.com
 Issue 5  has been merged into this issue.
Oct 23, 2009
Project Member #20 max.r...@gmail.com
I just posted a preview release of the JDO/JPA library to the downloads section of
the project:
http://datanucleus-appengine.googlecode.com/files/appengine-orm-1.0.4.RC1.zip

This release provides support for inheritance of native datastore types and embedded
classes.  Base classes with relationships are completely untested and probably do not
work.  If you're desperate to use inheritance in your object model please consider
downloading and installing.

You can find information on using inheritance in JDO here:
http://www.datanucleus.org/products/accessplatform_1_1/jdo/orm/inheritance.html
Note that app engine _only_ supports the 4th option, "complete-table."

You can find information on using inheritance in JPA here:
http://www.datanucleus.org/products/accessplatform_1_1/jpa/orm/inheritance.html
Note that app engine _only_ supports the 3rd option, "TABLE PER CLASS."

Please note that this is a preview release, so the only guarantee I can provide is
that the unit tests pass.
Nov 6, 2009
Project Member #21 max.r...@gmail.com
(No comment was entered for this change.)
Status: Fixed
Nov 6, 2009
#22 esig...@gmail.com
The TargetRelease is 1.0.4?
Nov 6, 2009
Project Member #23 max.r...@gmail.com
Yes, but that's the internal release number for the JDO/JPA project.  This will go
out with App Engine SDK 1.2.8
Nov 22, 2009
#24 rickh...@gmail.com
I installed the 1.0.4 patch JAR in the Eclipse plugin App Engine 1.2.6. I am now able 
to persist subclasses, but I still cannot query superclass fields. I have a simple 
example: Customer extends Person. Person has firstName as a property. When I save a 
customer, firstName is saved. But when I try a JDO query on firstName, I get the 
following error:

org.datanucleus.store.exceptions.NoSuchPersistentFieldException: Field "firstName" 
does not exist in com.bodyfixit.client.model.Customer or is not persistent
	at 
org.datanucleus.store.appengine.DatastoreTable.getMemberMapping(DatastoreTable.java:1
94)
	at 
org.datanucleus.store.appengine.query.DatastoreQuery.getMappingForFieldWithName(Datas
toreQuery.java:1022)
	at 
org.datanucleus.store.appengine.query.DatastoreQuery.addLeftPrimaryExpression(Datasto
reQuery.java:916)
	at 
org.datanucleus.store.appengine.query.DatastoreQuery.addExpression(DatastoreQuery.jav
a:715)
	at 
org.datanucleus.store.appengine.query.DatastoreQuery.addFilters(DatastoreQuery.java:6
63)
	at 
org.datanucleus.store.appengine.query.DatastoreQuery.performExecute(DatastoreQuery.ja
va:214)
	at 
org.datanucleus.store.appengine.query.JDOQLQuery.performExecute(JDOQLQuery.java:84)
	at org.datanucleus.store.query.Query.executeQuery(Query.java:1489)
	at org.datanucleus.store.query.Query.executeWithArray(Query.java:1371)
	at org.datanucleus.jdo.JDOQuery.execute(JDOQuery.java:243)
	... 35 more

Is this supposed to be working in 1.0.4? If not, will there be another patch issued 
soon to fix this? Thanks very much. My code follows:

Here is a shortened version of class Person:
--------------------------------------------

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Inheritance(strategy = InheritanceStrategy.UNSPECIFIED)
public class Person implements Serializable {

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value="true")
	private String key;
	private String firstName;
	
	public Person() {
	}

	public String getFirstName() {
		return (this.firstName);
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
}

Here is a shortened version of class Customer:
----------------------------------------------

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Customer extends Person implements Serializable {

	private String companyName;


	public Customer() {
	}

	public String getCompanyName() {
		return companyName;
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}
}

Here is the code used for the query:
------------------------------------

@Override
public Customer login(String firstName) {
	PersistenceManager pm = PMF.get().getPersistenceManager();
	Transaction txn = pm.currentTransaction();
	Query query = null;
	List<Customer> result = null;
	Customer c = null;
	try {
		txn.begin();
		Extent<Customer> customerExtent = pm.getExtent(Customer.class, true);
		String filter = "firstName == fn";
		query = pm.newQuery(customerExtent, filter);
		query.declareParameters("String fn");
		result = (List<Customer>) query.execute(firstName);
		if (result.size() > 0)
			c = result.get(0);
		txn.commit();
	} finally {
		if (query != null)
			query.close(result);
		if (txn.isActive()) {
			txn.rollback();
		}
		pm.close();
	}
	return c;
}
Nov 22, 2009
#25 david.so...@gmail.com
Hi

Shouldn't your firstName field have a @Persistent annotation?


David
Nov 22, 2009
Project Member #26 andy_jef...@yahoo.com
No. Many many java types don't need any @Persistent annotation since they are default
persistent, as per the JDO spec. The Google docs mislead people into thinking they do
Nov 23, 2009
Project Member #27 max.r...@gmail.com
Getting back to the original question posted by rickhoro, I'm not surprised to hear
this isn't working with the RC since I fixed a lot of bugs since I posted it.  Your
code works as expected with my most recent build, but unfortunately I won't have
another RC before the official SDK is released because I've introduced dependencies
on SDK changes that are not publicly available yet.  In otherwords, the code checked
into trunk is no longer compatible with SDK 1.2.6.  The new release should be up soon
though.  Thanks for the detailed report!
Nov 23, 2009
#28 rickh...@gmail.com
Thanks, Max. I really appreciate your efforts on getting this all working reasonably. 
These are key issues to fix and I'm really glad you're on it.
Nov 27, 2009
Project Member #29 max.r...@gmail.com
Heads up everybody, there is a preview release of the 1.2.8 SDK now available for
download at https://code.google.com/p/googleappengine/downloads/list.  This SDK is
only for local development (servers aren't updated yet) but it contains all the fixes
I made after I posted my own preview release awhile back.
Nov 29, 2009
#30 rickh...@gmail.com
This is weird...my app that was working a few days ago is now broken with 
inheritance, and I can't get it to work. Please, help! 

I've tried this with the Eclipse plugin with app engine 1.2.6 with the 1.0.4 patch, 
as well as the 1.2.8 sdk.

I have a class hierarchy that includes:

Person as a base class, with both Customer and Patient as subclasses that extend 
Person.

My app was working before I went out of town for Thanksgiving and I didn't change the 
code since then. The only thing I did was install the 1.2.8 SDK today, but strangely, 
now I cannot get it to work with either 1.2.8 or the 1.2.6 SDK upgraded with the 
1.0.4 patch that it was working with before. 

I get the error:

org.datanucleus.store.appengine.DatastoreManager$UnsupportedInheritanceStrategyExcept
ion: Found inheritance strategy 'superclass-table' on 
com.bodyfixit.client.model.Patient.  This strategy is not supported in this context. 

...depending on which SDK I use and how I configure it.

A few points:

1. In https://code.google.com/p/datanucleus-appengine/issues/detail?id=25#c20, Max 
notes that only "complete-table" inheritance strategy is supported, yet the 
@Inheritance annotation's InheritanceStrategy constants do not include a constant 
defined for "complete-table". (Note: previously, my code used an 
InheritanceStrategy.NEW_TABLE, and it worked. Now, it gives the inheritance strategy 
"superclass-table" error message, even though I specified NEW_TABLE.

2. I then tried to use XML to specify the inheritance strategy. I removed the 
@Inheritance annotation from my class files, and added the following config file 
(which I tried placing in either META-INF or the package directory for my Person, 
Patient, and Customer classes). Both gave me the same error message.

package.orm containing:

<?xml version="1.0"?>
<!DOCTYPE orm PUBLIC 
    "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN" 
    "http://java.sun.com/dtd/orm_2_0.dtd">
<orm>
    <package name="com.bodyfixit.client.model">
        <class name="Person">
            <inheritance strategy="complete-table"/>
        </class>
        <class name="Customer">
            <inheritance strategy="complete-table"/>
        </class>
        <class name="Patient">
            <inheritance strategy="complete-table"/>
        </class>
    </package>
</orm>

When I run the application, I get the same error message as above:

org.datanucleus.store.appengine.DatastoreManager$UnsupportedInheritanceStrategyExcept
ion: App Engine does not support Inheritance Strategy superclass-table.

Following are shortened versions of my classes:


Here is a shortened version of class Person:
--------------------------------------------

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Person implements Serializable {

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value="true")
	private String key;
	private String firstName;
	
	public Person() {
	}

	public String getFirstName() {
		return (this.firstName);
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
}

Here is a shortened version of class Customer:
----------------------------------------------

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Customer extends Person implements Serializable {

	private String companyName;


	public Customer() {
	}

	public String getCompanyName() {
		return companyName;
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}
}

Here is a shortened version of class Patient:
---------------------------------------------

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Patient extends Person implements Serializable {

	/**
	 * Serializable version id
	 * When evolving this class with compatible changes, copy this version id
	 * to the new class
	 */
	static final long serialVersionUID = 100L;

	/** The user's mailing address */
	@Persistent
	private Address address = new Address();

	public Address getAddress() {
		return (this.address);
	}

	public void setAddress(Address address) {
		this.address = address;
	}
}

Please help if you can. I have no idea why this isn't working anymore and could 
really use some help.

Thanks,

Rick


Nov 29, 2009
Project Member #31 max.r...@gmail.com
Hi Rick,

The following will allow you to persist instances of your Person class in addition to
Patient and Customer (I'm assuming that's what you want):

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Inheritance(customStrategy = "complete-table")
public class Person { ... }

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Inheritance(customStrategy = "complete-table")
public class Customer { ... }

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Inheritance(customStrategy = "complete-table")
public class Patient { ... }

Note the use of the "customStrategy" attribute as opposed to the "strategy" attribute.

Hope this helps,
Max
Dec 7, 2009
#32 ivanCe...@gmail.com
Hi Max, I have read about the model inheritance on complete-table, I have a question.
Using your example, If a patient is added with specified firstName, and lastName, 
then a corresponding table of "Customer" and "Person" also contains the firstName and 
lastName. I assume that if you modify the firstName and lastName in "Patient" object 
the firstName and lastName on "Customer" and "Person" is also updated, But how about 
if you modify the firstName and the lastName using the "Customer" object? will it 
also change the firstName and lastName in "Person" Object? in "Patient" object?

Please clarify.

Regards,
ivan ceras
Dec 8, 2009
Project Member #33 max.r...@gmail.com
A record only lives in one "table" at a time.  If you have an object whose runtime type 
is Patient, that object lives in the Patient table and only that table.  If you have an 
object whose runtime type is a Customer, that object lives in the Customer table and 
only that table.  If you have an object whose runtime type is Person, that object lives 
in the Person table and only that table.  Updating the firstName of a Customer object 
will only update a record in the Customer table because the entity is only present in 
the Customer table.

Hope this helps,
Max
Jan 12, 2010
#34 arnold.m...@gmail.com
I am working with App Engine SDK 1.3.0 and retrieving inherited object as described 
in the document below seems not to work:
http://www.datanucleus.org/products/accessplatform/jdo/orm/inheritance.html#Retrieval
_of_inherited_objects .

I have a root class and a subclass like so:
--------------------------------------
@PersistenceCapable(detachable="false")
@Inheritance(customStrategy = "complete-table")
public class Event{
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
	private String key;
}
--------------------------------------
@PersistenceCapable(detachable="false")
public class ObjectView extends Event{

}
--------------------------------------

And the code below does not return any results even though there are instances of the 
subclass ObjectView in the datastore.

			Extent<Event> extent = pm.getExtent(Event.class, true);
			Query q = pm.newQuery(extent);
			q.setRange(0, 10);
			Collection<Event> events = (List<Collection>)q.execute();

And in debug mode, extent.hasSubclasses() is false.

(But retrieving the sub-class ObjectView instances works.)

Am I expecting too much?

Otherwise, great job max!
Jan 12, 2010
Project Member #35 max.r...@gmail.com
Thanks for the report!  Unfortunately returning an Extent with subclasses is currently 
unsupported.  You can see it here:
http://www.google.com/codesearch/p?
hl=en#79kbA0UmWLw/trunk/src/org/datanucleus/store/appengine/DatastoreMana
ger.java&q=return new DefaultCandidateExtent package:http://datanucleus-
appengine\.googlecode\.com&sa=N&cd=1&ct=rc&l=250

I should probably be throwing an exception here, or at least logging, rather than 
silently ignoring the param.  Would you mind filing a separate issue?

Thanks,
Max
Jan 12, 2010
#36 arnold.m...@gmail.com
Thanks Max. It looks like I was expecting too much then :-)

Yes, throwing a useful exception will be helpful. 

I have file an issue for this here:
https://code.google.com/p/datanucleus-appengine/issues/detail?id=187

Regards,
Arnold.
Jan 25, 2010
Project Member #37 max.r...@gmail.com
(No comment was entered for this change.)
Status: Verified
Feb 11, 2010
#38 adelaney...@gtempaccount.com
I just read that the SDK release yesterday included new support for inheritance, and 
it lead me to this page.  I don't see any further description of what sort of support 
was introduced.  I just started looking at AppEngine to port my existing practice 
management software over to web application from winforms, and my fist issues concern 
the support of the database for inheritance.  On monday, seeing that the datastore 
did not support unrestricted new-table or super-table inheritance strategies, I 
started to design a workaround.  However, if GAE will very soon support my needs, I 
can abandon that to work on my project in chief.  I have several MUST HAVES for 
porting purposes:

1.  All dynamic user data in my application derives and inherits from a single root 
class.  I need to store that either with JDO new-table or JDO superclass-table 
capabilities.  I have started to fashion a solution that uses a single private 
persistent core item for storage purposes, and multiple levels of non-persistent 
classes that expose the portions of the core persistent item as needed.  Is this 
still necessary, or can I now store all levels of inherited persistent objects in a 
single superclass-table?

2.  Polymorphic Query Results:  I need to be able to query the database and retrieve 
all object instances that are at or below the query level, i.e.  if I have a class 
called Person, with two subclasses, Attorney and Client, and Client has two 
subclasses, Personal and Corporate, I need to be able to run a query on Client and 
receive all Client, Personal, and Corporate Items that match the query

3.  Polymorphic Query Criteria:  I need to be able to search on the Client table 
above, but filter on fields in the Person table it inherits from.

4.  Polymorphic relationships:  Does the new version fully support polymorphic 
relationships, such that I can relate a Case to a "Client" from above, and have that 
refer to a Client, a PersonalClient, or a Corporate Client?

Michael DeLaney
Conquerence Solutions
Feb 16, 2010
#39 eric1...@gmail.com
I've found lots of great advice about how to persist entities in an inheritance tree, but I haven't found much 
help regarding how to retrieve those same entities.

I have an inheritance model that looks like this:

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public class Item {

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

@PersistenceCapable
public class ItemTypeA extends Item {
}

@PersistenceCapable
public class ItemTypeB extends Item {
}

@PersistenceCapable
public class ItemTypeC extends Item {
}

I create an instance of one of the subclasses and persist to the datastore:

Item item = ItemFactory.create(Item.ItemTypeA);
pm.makePersistent(item);

When I try to retrieve the subclass instance, I get the following exception:

Item item = (Item) pm.getObjectById(Item.class, itemKey);

javax.jdo.JDOObjectNotFoundException: No such object
FailedObject:ItemTypeA(87)
	at 
org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:323)
	at org.datanucleus.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1676)
	at org.datanucleus.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1652)
...

I've tried using both SUBCLASS_TABLE and complete-table for the inheritance strategy of the base Item class 
without any luck.

A couple of questions then:

1) Can I directly retrieve an instance of the subclass or do I need to always query for the superclass instance?

2) If I can query directly for the subclass, do I specify the subclass type or superclass type as parameter #1 in 
the call to getObjectById() ?

3) If I have to retrieve based on the superclass type, can I treat the returned object as an instance of the 
subclass (downcast)?

If there is any good documentation about retrieving objects in an inheritance hierarchy I'd really appreciate 
someone pointing me to it.

Thanks very much!

Eric

Feb 17, 2010
Project Member #40 max.r...@gmail.com
@adelaney:
Inheritance support has been out since late last year.  The docs are here
https://code.google.com/appengine/docs/java/datastore/dataclasses.html#Inheritance
Feb 17, 2010
Project Member #41 max.r...@gmail.com
@eric12au:
1) You can only query for instances of the subclass.  There are no "tables" in the 
datastore so all your data lives in a single record with its "kind" equal to the subclass.

2) Specify the subclass type as the param value

There isn't any documentation specifically geared towards retrieving objects that 
have super classes.  The best advice I can give is that for the purposes of querying, 
pretend that all your state is declared on the subclass and don't think about the 
inheritance.
Feb 17, 2010
#42 eric1...@gmail.com
Hey Max,

Thanks for the response. While I understand what you describe, it seems to me that not being able to query 
for the superclass type defeats part of the beauty of using inheritance in the first place.  I'd like to be able to 
execute a query that returns, say, List<Item> (where Item is the superclass) and then iterate over the Items 
without needing to know the particular subclass of each Item.  As I iterate, I can call a method defined by the 
superclass and overridden by the subclasses, basic polymorphic behavior.  If I need to know the particular 
subclass type to query for, there's really little point in using inheritance, at least from the perspective of 
persisting and retrieving the data.

I was briefly encouraged by a bit of the DataNucleus documentation, specifically the following taken from this 
link: http://www.datanucleus.org/products/accessplatform/jdo/orm/inheritance.html

Retrieval of inherited objects

JDO provides particular mechanisms for retrieving inheritance trees. These are accessed via the Extent/Query 
interface. Taking our example above, we can then do

tx.begin();
Extent e = pm.getExtent(com.mydomain.samples.store.Product.class, true);
Query  q = pm.newQuery(e);
Collection c=(Collection)q.execute();
tx.commit();

The second parameter passed to pm.getExtent relates to whether to return subclasses. So if we pass in the 
root of the inheritance tree (Product in our case) we get all objects in this inheritance tree returned. You can, 
of course, use far more elaborate queries using JDOQL, and SQL but this is just to highlight the method of 
retrieval of subclasses.

Is this behavior that is not supported by app engine's JDO implementation?  I've tried it and not been able to 
retrieve subclasses as the above documentation says I can, so I'm assuming app engine doesn't support this, 
but it can't hurt to ask. =)

Again, thanks for taking the time to respond.

- Eric
Feb 18, 2010
#43 arnold.m...@gmail.com
Hey Eric,

As u may have noticed in some posts above, retrieving of inherited objects via Extent/Query 
mechanism is currently not supported.

While I some what understand why we should live with that for the moment, I also think 
marking an issue named like this as Fixed and Verified is kind of misleading. We should 
therefore expect more such questions from time to time from people who are trying to use 
inheritance for the first time in GAE because once one says there is support for 
inheritance one would assume it means there is support for persisting inheritance trees AND 
retrieving them.

Imho, may be this issue should be named "Support for persisting inheritance trees" or 
something else with better English and that specific, and then there should be another 
issue "Support for retrieving inheritance trees" that we would hope and pray to be fixed in 
the future.

Regards,
Arnold.
Sign in to add a comment

Powered by Google Project Hosting