I am trying to persist a JPA entity with a collection of custom @Embeddable objects using the JPA2 @ElementCollection annotation. Simple example (both classes are enhanced by datanucleus):
@Entity
public class TestEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ElementCollection
private Set<TestEmbeddable> testEmbeddables;
public Set<TestEmbeddable> testEmbeddables() {
return this.testEmbeddables;
}
}
@Embeddable
public class TestEmbeddable implements Serializable {
public String s;
}
The persisted Datastore entity, however, will only contain a collection of null values instead of the actual objects:
TestEntity.testEmbeddables = [null, null, ...]
Persisting a collection of basic types such as Strings or embedding a single TestEmbeddable object using @Embedded works perfectly fine. Would someone be able to clarify whether element collections of embeddables are supported by datanucleus-appengine?
While the datanucleus section on JPA element collections only gives an example for a String collection, the corresponding JDO section uses a custom embedded-only type. The feature list further states that embedded collections in general are compatible with GAE, but does not say whether custom types are supported. I also found one other person claiming that this should work.
-- Edit --
Following DataNucleus' answer, I ran some more tests:
@ElementCollection
private List<String> stringsElementCollection;
--> Works. The individual Strings are persisted as TestEntity.stringsElementCollection = [str1, str2, ...]
@Embedded
private List<String> stringsEmbedded;
--> Same as @ElementCollection. I wonder if the JPA specification covers the use of @Embedded on a collection, though?
@ElementCollection
private List<TestEmbeddable> embeddablesElementCollection;
--> Doesn't work. Instead of the actual TestEmbeddable objects, the Datastore persists only a collection of null values: TestEntity.embeddablesElementCollection = [null, null, ...]
@Embedded
private List<TestEmbeddable> embeddablesEmbedded;
--> This seems to work. The TestEmbeddable.s field is stored as TestEntity.s.0, .s.1, etc. plus a TestEntity.embeddablesEmbedded.size property.
(App Engine SDK 1.7.7.1, datanucleus 3.1.3, datanucleus-appengine 2.1.2)
No idea if Google support embedded collections of such objects yet with JPA. That was only developed for JDO and works there. You could try putting a @Embedded on the embedded field to reinforce the idea that its embedded.
The issue has been recorded by David Geiger here: https://code.google.com/p/datanucleus-appengine/issues/detail?id=318