I'm trying to persist a simple class relationship using JDO. My code
is listed below and here's a brief overview of what I'm trying to do:
I have 3 classes:
Person, Customer (extends Person), and Address (referenced from
Person). If I create a Person instance and an Address instance and
call setAddress() on Person, then call
PersistenceManager.makePersistent(), the objects get saved correctly.
However, if I create a Customer instance and an Address instance, I
get the following error message:
java.lang.IllegalArgumentException: can't operate on multiple entity
groups in a single transaction. found both Element {
type: "Customer"
id: 1
}
and Element {
type: "Address"
id: 2
}
I am doing this from within a JDO transaction.
Here's the code:
First, the server-side code that attempts to create and persist the
objects:
-----------------------------------------------------------------------------------------------------------
PersistenceManager pm = PMF.get().getPersistenceManager();
Transaction txn = pm.currentTransaction();
try {
txn.begin();
Address a = new Address("15 Post Road", "", "Anytown",
"New York",
"USA", "03801");
Customer c = new Customer();
c.setAddress(a);
c.setFirstName("John");
c.setLastName("Doe");
pm.makePersistent(c);
txn.commit();
} finally {
if (txn.isActive()) {
txn.rollback();
}
pm.close();
}
Person:
-----------
@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public abstract class Person implements Serializable {
public static enum PERSON_KEYS {
firstName,
lastName,
workEmail,
phoneNbr
}
static final long serialVersionUID = 100L;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk",
value="true")
private String key;
private String firstName;
private String lastName;
private String middleInitial;
private String workEmail;
private String homeEmail;
private String phoneNbr;
@Persistent
private Address address = new Address();
private String salutation;
public Person() {
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getWorkEmail() {
return (this.workEmail);
}
public void setWorkEmail(String workEmail) {
this.workEmail = workEmail;
}
public String getHomeEmail() {
return homeEmail;
}
public void setHomeEmail(String homeEmail) {
this.homeEmail = homeEmail;
}
@NotPersistent
public String getEmailAddress() {
String emailAddr = getWorkEmail();
if ((emailAddr == null) || (emailAddr.length() ==0))
emailAddr = getHomeEmail();
return emailAddr;
}
public void setEmailAddress(String emailAddress) {
setWorkEmail(emailAddress);
}
@NotPersistent
public String getFullName() {
StringBuffer sb = new StringBuffer();
if (getFirstName() != null) {
sb.append(getFirstName());
sb.append(" ");
}
if ((getMiddleInitial() != null) &&
(getMiddleInitial().length() >
0)) {
sb.append(getMiddleInitial());
sb.append(" ");
}
if (getLastName() != null) {
sb.append(getLastName());
}
return sb.toString();
}
public String getFirstName() {
return (this.firstName);
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return (this.lastName);
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Address getAddress() {
public void setAddress(Address address) {
this.address = address;
}
public String getMiddleInitial() {
return middleInitial;
}
public void setMiddleInitial(String middleInitial) {
this.middleInitial = middleInitial;
}
public String getPhoneNbr() {
return phoneNbr;
}
public void setPhoneNbr(String phoneNbr) {
this.phoneNbr = phoneNbr;
}
}
Customer:
---------------
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Customer extends Person implements Serializable {
static final long serialVersionUID = 100L;
public static enum CUSTOMER_KEYS {
username,
password,
companyName,
}
public static int FT_STATUS_OK = 0;
public static int FT_STATUS_ACTIVE_FREE_TRIAL = 1;
public static int FT_STATUS_ACTIVE_FREE_TRIAL_EXT = 2;
public static int FT_STATUS_RECENT_FREE_TRIAL = 4;
public static int FT_STATUS_RECENT_FREE_TRIAL_EXT = 8;
private String username;
private String password;
private String companyName;
private int freeTrialStatus;
public Customer() {
}
public String getUsername() {
return (this.username);
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return (this.password);
}
public void setPassword(String password) {
this.password = password;
}
public int getFreeTrialStatus() {
return freeTrialStatus;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
}
Address
------------
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Address implements java.io.Serializable {
static final long serialVersionUID = 100L;
public static enum ADDRESS_KEYS {
address1, address2, city, state, country, postalCode
}
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk",
value="true")
private String key;
private Long version;
private String address1;
private String address2;
private String city;
private String state;
private String country;
private String postalCode;
public Address() {
}
/**
* Construct the address
*
* @param address1
* Address line 1
* @param address2
* Address line 2
* @param city
* The city
* @param state
* The state
* @param country
* The country
* @param postalCode
* Postal/ZIP code
*/
public Address(String address1, String address2, String city, String
state,
String country, String postalCode) {
this.address1 = address1;
this.address2 = address2;
this.city = city;
this.state = state;
this.country = country;
this.postalCode = postalCode;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress1() {
return this.address1;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getAddress2() {
return this.address2;
}
public void setCity(String city) {
this.city = city;
}
public String getCity() {
return this.city;
}
public void setState(String state) {
this.state = state;
}
public String getState() {
return this.state;
}
public void setCountry(String country) {
this.country = country;
}
public String getCountry() {
return this.country;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getPostalCode() {
return this.postalCode;
}
}
The full stack trace for the exception:
------------------------------------------------------
Caused by: java.lang.IllegalArgumentException: can't operate on
multiple entity groups in a single transaction. found both Element {
type: "Customer"
id: 1
}
and Element {
type: "Address"
id: 2
}
at
com.google.appengine.api.datastore.DatastoreApiHelper.translateError
(DatastoreApiHelper.java:33)
at com.google.appengine.api.datastore.DatastoreApiHelper.makeSyncCall
(DatastoreApiHelper.java:60)
at com.google.appengine.api.datastore.DatastoreServiceImpl$2.run
(DatastoreServiceImpl.java:173)
at
com.google.appengine.api.datastore.TransactionRunner.runInTransaction
(TransactionRunner.java:30)
at com.google.appengine.api.datastore.DatastoreServiceImpl.put
(DatastoreServiceImpl.java:161)
at com.google.appengine.api.datastore.DatastoreServiceImpl.put
(DatastoreServiceImpl.java:141)
at com.google.appengine.api.datastore.DatastoreServiceImpl.put
(DatastoreServiceImpl.java:137)
at
org.datanucleus.store.appengine.RuntimeExceptionWrappingDatastoreService.put
(RuntimeExceptionWrappingDatastoreService.java:105)
at org.datanucleus.store.appengine.DatastorePersistenceHandler.put
(DatastorePersistenceHandler.java:172)
at org.datanucleus.store.appengine.DatastorePersistenceHandler.put
(DatastorePersistenceHandler.java:112)
at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects
(DatastorePersistenceHandler.java:239)
at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject
(DatastorePersistenceHandler.java:225)
at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent
(JDOStateManagerImpl.java:3185)
at org.datanucleus.state.JDOStateManagerImpl.makePersistent
(JDOStateManagerImpl.java:3161)
at org.datanucleus.ObjectManagerImpl.persistObjectInternal
(ObjectManagerImpl.java:1298)
at
org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObjectAsValue
(PersistenceCapableMapping.java:604)
at
org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObject
(PersistenceCapableMapping.java:364)
at org.datanucleus.store.appengine.DatastoreRelationFieldManager
$1.setObjectViaMapping(DatastoreRelationFieldManager.java:132)
at org.datanucleus.store.appengine.DatastoreRelationFieldManager
$1.apply(DatastoreRelationFieldManager.java:108)
at
org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelations
(DatastoreRelationFieldManager.java:80)
at
org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations
(DatastoreFieldManager.java:795)
at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostProcess
(DatastorePersistenceHandler.java:288)
at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects
(DatastorePersistenceHandler.java:241)
at
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject
(DatastorePersistenceHandler.java:225)
at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent
(JDOStateManagerImpl.java:3185)
at org.datanucleus.state.JDOStateManagerImpl.makePersistent
(JDOStateManagerImpl.java:3161)
at org.datanucleus.ObjectManagerImpl.persistObjectInternal
(ObjectManagerImpl.java:1298)
at org.datanucleus.ObjectManagerImpl.persistObject
(ObjectManagerImpl.java:1175)
at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent
(JDOPersistenceManager.java:669)
... 36 more
--
You received this message because you are subscribed to the Google Groups
"Google App Engine" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine?hl=.