Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded Enums generate "Not a supported property type" on insert #6

Open
macosgrove opened this issue Oct 17, 2011 · 1 comment
Open

Comments

@macosgrove
Copy link

I have a Singer class with multiple references to a VoicePart enum. I have set up the Singer like this:

public class Singer extends SaiEntity {
@id(Generator.AUTO_INCREMENT)
protected Long id;
@Embedded
protected List voiceParts;
...
}

and the enum is...

public enum VoicePart {
TENOR("Tenor", 1L),
LEAD("Lead", 2L),
BARI("Baritone", 3L),
BASS("Bass", 4L);
private String name;
private Long value;

VoicePart(String name, Long value) {
    this.name = name;
    this.value = value;
}

public String getName() {
    return name;
}

public Long getValue() {
    return value;
}

...
}

When I try to insert a Singer, I get the following exception:

java.lang.IllegalArgumentException: voiceParts: models.enums.VoicePart is not a supported property type.
at com.google.appengine.api.datastore.DataTypeUtils.checkSupportedSingleValue(DataTypeUtils.java:184)
at com.google.appengine.api.datastore.DataTypeUtils.checkSupportedValue(DataTypeUtils.java:149)
at com.google.appengine.api.datastore.DataTypeUtils.checkSupportedValue(DataTypeUtils.java:123)
at com.google.appengine.api.datastore.Entity.setProperty(Entity.java:320)
at siena.gae.GaeMappingUtils.fillEntity(GaeMappingUtils.java:473)
at siena.gae.GaePersistenceManager._insertSingle(GaePersistenceManager.java:284)
at siena.gae.GaePersistenceManager._insertSingle(GaePersistenceManager.java:267)
at siena.gae.GaePersistenceManager.insert(GaePersistenceManager.java:253)
at siena.Model.insert(Model.java:79)
at models.TestSinger.createTenSingers(TestSinger.java:37)
at models.TestSinger.setup(TestSinger.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at play.test.PlayJUnitRunner$StartPlay$1$1$1.execute(PlayJUnitRunner.java:73)
at play.Invoker$Invocation.run(Invoker.java:265)
at play.Invoker.invokeInThread(Invoker.java:67)
at play.test.PlayJUnitRunner$StartPlay$1$1.evaluate(PlayJUnitRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at play.test.PlayJUnitRunner.run(PlayJUnitRunner.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

@mandubian
Copy link
Owner

Oh sorry, this morning I read Embedded as Aggregated :D
I was convinced that you had a problem of aggregation. But no, you have a problem of EMBEDDING...
and I can tell you that what you try to do is not possible with embedding at all.
Here you try to use default embedding which is Json serialization.
You can't embed a List of enum like that because the JSON serializer requires a @EmbeddedMap or @EmbeddedList annotation on the embedded class. Yet, you use an Enum (with 2 fields on top of that) and the JSON serializer don't know how to manage this. So your behavior is quite "normal" as it doesn't try to do anything and just as GAE persistence manager to store which then refuses to do it.

I imagine you want to perform filter/orders on this embedded field later, isn't it? WIth JSON, it's not possible as you may imagine. The easiest way might be to use the GAE native List Property with a primitive type such as String.

public class Singer extends SaiEntity {
@id(Generator.AUTO_INCREMENT)
protected Long id;

protected List<String> voiceParts;
//...
}

If you absolutely need to store VoicePart objects, there are other solution with aggregation also.

Don't hesitate to ask on the mailing list if you have questions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants