Thank you for responding. This is not good, but I guess it could be worse.
Google could be ignoring these problems instead of fixing them. One more
question. What's the right way to install appengine-orm-1.0.4.rc1.zip with
the Eclipse App Engine SDK 1.2.6? Do I just replace all the jars in the SDK
with the jars from appengine-orm-1.0.4.rc1.zip?

Thanks very much.

Rick

On Thu, Nov 19, 2009 at 5:03 PM, Ikai L (Google) <[email protected]> wrote:

> The current version won't support inheritance, which may explain why this
> isn't working. It looks like fixes for inheritance will be going out when
> datanucleus is updated:
>
> http://code.google.com/p/datanucleus-appengine/issues/detail?id=25
>
> The stack trace looks different, though, but that may be because you are
> using a transaction, and the transaction manager is taking a look at the key
> that is being generated and does not recognize "Address" as having
> "Customer" as an ancestor.
>
> I'm not sure why you need a transaction here, though. It doesn't look like
> Customer or Address will be out of sync. You could also accomplish the same
> thing using an embedded class, though I suppose that wouldn't work if
> multiple customers had the same address and addresses changed frequently
> (though you could solve this by updating all matching embedded addresses if
> an address changes in a transaction, making the Address the parent of the
> Customer).
>
> ---------- Forwarded message ----------
> From: Rick Horowitz <[email protected]>
> Date: Thu, Nov 19, 2009 at 1:44 PM
> Subject: [google-appengine] Re: Can't get owned relationship working with
> JDO and subclass
> To: Google App Engine <[email protected]>
>
>
> Does anyone have any idea why this won't work? I've tried every option
> I can think of and it still doesn't work. Would really appreciate some
> help from someone knowledgeable about JDO and gae. I'm assuming it's
> pretty basic to persist a subclass object whose superclass (base
> class) references an owned object, but gae doesn't seem to like it. I
> tried the base class as abstract and concrete, and tried the keys as
> type Key and as encoded String. No luck.
>
> Thanks very much for any help.
>
> Rick
>
> On Nov 15, 11:40 pm, Rick Horowitz <[email protected]> wrote:
> > 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]<google-appengine%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-appengine?hl=.
>
>
>
>
>
> --
> Ikai Lan
> Developer Programs Engineer, Google App Engine
>
> --
> 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]<google-appengine%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-appengine?hl=.
>

--

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=.


Reply via email to