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 google-appeng...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=.


Reply via email to