How do I annotate a collection of embedded objects in Google App Engine (Java)?
Is it possible to store a collection of embedded classes in Google App Engine (Java)? If so, how would I annotate it?
This is my class:
@PersistenceCapable
public class Employee
{
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
Key key;
@Persistent(embeddedElement = "true")
private List<ContactInfo> contactDetails = new ArrayList<ContactInfo>();
public void addContactInfo(String streetAddress, String city)
{
this.contactDetails.add(new ContactInfo(streetAddress, city));
}
public List<ContactInfo> getContactDetails()
{
return this.contactDetails;
}
@PersistenceCapable
@EmbeddedOnly
public static class ContactInfo
{
@Persistent
private String streetAddress;
@Persistent
private String city;
public ContactInfo(String streetAddress, String city)
{
this.streetAddress = streetAddress;
this.city = city;
}
public String getStreetAddress()
{
return this.streetAddress;
}
开发者_开发问答 public String getCity()
{
return this.city;
}
}
}
Here is the test code:
// Create the employee object
Employee emp = new Employee();
// Add some contact details
emp.addContactInfo("123 Main Street", "Some City");
emp.addContactInfo("50 Blah Street", "Testville");
// Store the employee
PersistenceManager pm = PMF.get().getPersistenceManager();
try
{
pm.makePersistent(emp);
}
finally
{
pm.close();
}
// Query the datastore for all employee objects
pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery(Employee.class);
try
{
List<Employee> employees = (List<Employee>) query.execute();
// Iterate the employees
for(Employee fetchedEmployee : employees)
{
// Output their contact details
resp.getWriter().println(fetchedEmployee.getContactDetails());
}
}
finally
{
query.closeAll();
pm.close();
}
The test code always outputs 'null'. Any suggestions?
I've tried annotating the contactDetails list as @Embedded, but the DataNucleus enhancer threw an exception. I've also tried adding defaultFetchGroup = "true" to the @Persistent annotation on the contactDetails list (in case it was a problem with fetching the data), but the output was still null. I've examined the employee object in the console and there's no evidence of any contact detail fields being stored on the object, nor are there any stand-alone ContactInfo objects in the datastore (not that I'd expect there to be, given they are embedded objects).
Is this even possible to do? I know that the fields of an embedded class are stored as properties on the entity, so I can see how field name conflicts might arise in a collection scneario, but the App Engine docs don't explicitly say it cannot be done.
I don't know if you need the answer still but putting the List into the defaultFetchGroup solved this issue for me:
@PersistenceCapable
public class Employee
{
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
Key key;
@Persistent(embeddedElement = "true", defaultFetchGroup = "true")
private List<ContactInfo> contactDetails = new ArrayList<ContactInfo>();
// Snip...
}
With JDO you would do it as per the DataNucleus docs http://www.datanucleus.org/products/accessplatform_2_2/jdo/orm/embedded.html#Collection The example shows XML, but the annotation names are approximately equivalent.
Whether GAE/J's plugin supports this I couldn't say since it's Google's responsibility. Maybe try it?
精彩评论