Search code examples
google-app-enginegwtjdo

JDO javax.jdo.JDOFatalUserException


First of all, I am kinda a noob on this. So, I am trying to build a WebApp using GWT2.6.1 and GAE1.9.9.

I've done something like this...

@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public abstract class Person implements IsSerializable {

    @PrimaryKey
    @Persistent
    private String googleUserID;
    @Persistent
    private String name;
    @Persistent
    private String secondName;
    @Persistent
    private String surname;
    @Persistent
    private Boolean isActive = false; //default value
    @Persistent
    private String imageURL;
    ...
}

then,

@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
public abstract class User extends Person implements IsSerializable{

    @Persistent
    private String email;
    ...
}

and finally,

@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
public class Admin extends User implements IsSerializable, Serializable {

    private static final long serialVersionUID = 1L;

    @NotPersistent
    public static final AccountTypes accountType = AccountTypes.Admin;
    ...
}

Then I am getting the following error:

javax.jdo.JDOFatalUserException: Found inheritance strategy "new-table" on epusp.pcs.os.model.person.user.Admin. This strategy is not supported in this context. Please see the documentation for information on using inheritance with JDO: http://code.google.com/appengine/docs/java/datastore/dataclasses.html#Inheritance

I read the documentation, but I still don't understand what I am doing wrong. Can anyone give me a hint?

PS.: I know, I know, I plan to add some new attributes to Admin and User in the future. Basically what I want to do is to check if a User is registered in database using a GoogleID and then redirect him to a specifed URL based on his AccountType (it may be an Admin, SuperUser, Auditor ...). I was doing something like this:

PersistenceManager pm = PMF.get().getPersistenceManager();
Admin user = null;
try{
    user = pm.getObjectById(User.class, userId);
}finally{
    pm.close();
}
switch(user.getType()){
case Admin:
    return "";
case Agent:
    return "";
case Auditor:
    return "";
case Monitor:
    return "";
case SuperUser:
    return "";
default:
    return null;
}

Thanks for supporting!


Solution

  • The "new-table" inheritance strategy allows you to split the data for a single data object across multiple "tables," but since the App Engine datastore does not support joins, operating on a data object with this inheritance strategy requires a remote procedure call for each level of inheritance. This is potentially very inefficient, so the "new-table" inheritance strategy is not supported on data classes that are not at the root of their inheritance hierarchies.

    Second, the "superclass-table" inheritance strategy allows you to store the data for a data object in the "table" of its superclass. Although there are no inherent inefficiencies in this strategy, it is not currently supported. We may revisit this in future releases.

    Now the good news: The "subclass-table" and "complete-table" strategies work as described in the DataNucleus documentation, and you can also use "new-table" for any data object that is at the root of its inheritance hierarchy.