asolfre / objectify-appengine

Automatically exported from code.google.com/p/objectify-appengine
MIT License
0 stars 0 forks source link

Support for polymorphic hierarchy with abstract base class #128

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
1. Create an abstract base class
2. Extend the previous class with a concrete class
3. Register these classes in objectify

Both classes will fail to register with an error:
"Unable to construct an instance of 'class' perhaps it has no suitable 
constructor?"

I'm using Objectify 4.0a3, Guice 3, Resteasy 2.3.2 and GAE SDK 1.6.6.
Running Mac OSX 10.6.8.

Temporary workaround:

"Make your class concrete and instead of declaring abstract methods, make them 
throw UnsupportedOperationException(). Not quite as typesafe but it will 
get you over the hurdle for now."

Original issue reported on code.google.com by jmandra...@gmail.com on 6 Jun 2012 at 11:07

GoogleCodeExporter commented 9 years ago

Original comment by lhori...@gmail.com on 6 Jun 2012 at 11:27

GoogleCodeExporter commented 9 years ago
I encountered the same exception upon upgrading from 4.0b1 to 4.0rc1.

In my case the class that fails is an enum type that has no default 
constructor.  Maybe that should be exception just as abstract classes are an 
exception (abstract appears to have been addressed in rc1).

The entity is:

/**
  MyEntity enumerated value. It should not have a default constructor because
  all defined enumerators set the underlying "this.value" property.
  */
class enum MyEntity {
  X("x), Y("y"), Z("z");
  private final String value;
  MyEntity(value) {
    this.value = value;
  }
}

Here is the code in question in ClassTranslator.java:

public ClassTranslator(Class<T> clazz, Path path, CreateContext ctx)
{
        this.fact = ctx.getFactory();
        this.clazz = clazz;

        if (log.isLoggable(Level.FINEST))
            log.finest("Creating class translator for " + clazz.getName() + " at path '"+ path + "'");

        // Quick sanity check - can we construct one of these?  If not, blow up.  But allow abstract base classes!
        if (!Modifier.isAbstract(clazz.getModifiers())) {    <<<< Should exclude enum also? <<<<<<
            try {
                fact.construct(clazz);
            } catch (Exception ex) {
                throw new IllegalStateException("Unable to construct an instance of " + clazz.getName() + "; perhaps it has no suitable constructor?", ex);
            }
        }
.
.
}

Original comment by jim.trai...@gmail.com on 4 Oct 2013 at 8:20

GoogleCodeExporter commented 9 years ago
You cannot use an enum as an entity. You can use an enum as a field in an 
entity, but it can't be an entity itself. How would that work? Enums don't have 
@Id fields or modifiable properties.

Thank you for reminding me though - this issue has been fixed. 4.0rc1 lets you 
use abstract base classes.

Original comment by lhori...@gmail.com on 4 Oct 2013 at 2:59