I'm using the Google App Engine in combination with the Google Web Toolkit to write a bug tracker (to see what the technologies are capable of).
Modelled after Google Code's issue tracker, I decided that an issue can have 0 or more labels, that can be defined beforehand (let's say in the settings).
The label class (CustomLabel):
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class CustomLabel implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
private String encodedKey;
@Persistent
@Extension(vendorName="datanucleus", key="gae.pk-id", value="true")
private Long keyId;
/**
* label caption.
*/
@Persistent
private String caption;
// Unimportant getters / setters
}
Now the parent class (Issue):
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Issue implements Serializable {
private static final long serialVersionUID = 1L;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
// Replacing the Long key by this key doesn't make a difference
// @PrimaryKey
// @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
// @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
// private String encodedKey;
@Persistent
private String summary;
@Persistent
private String description;
@Persistent
private ArrayList<CustomLabel> labels;
// Other details
}
When I'm trying to persist a new Issue with existing CustomLabels I get the following exception:
org.datanucleus.exceptions.NucleusUserException: Detected attempt to establish Issue(11) as the parent of CustomLabel(1) but the entity identified by CustomLabel(1) has already been persisted without a parent. A parent cannot be established or changed once an object has been persisted.
How can this be solved? I cannot use Key's and create an unowned relationship, since I'm sending the objects to the GWT front-end (which is compiled to Javascript and com.google.appengine.api.datastore.Key isn't supported). Besides that would break referential integrity, which is undesirable.