views:

429

answers:

1

I have three entities User, Company, and Address with declarations like so:

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class User implements Serializable {
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent(mappedBy="creator")
  @Order(extensions = @Extension(vendorName="datanucleus", key="list-ordering", value="title asc"))
  private Collection<Company> companies;

  @Persistent
  private Address address;
  . . . 
}

public class Company implements Serializable {
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent
  @Extension(vendorName="datanucleus", key="gae.parent-pk", value="true")
  private Key creatorKey;

  @Persistent
  private User creator;

  @Persistent
  private Address address;
  . . .
}

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Address implements Serializable{
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;
  . . .
}

After creating a user I then persist two companies owned by a user after setting their addresses and other information like so:

company.setCreatorKey(currentUser.getKey());
pm.makePersistent(company);

The problem arises when I retrieve a company and from that object reference the creator. Apparently JDO thinks that the addresses of the two companies belong to the user as opposed to the companies and the following error is logged:

address is mapped as a 1 to 1 relationship but there is more than one enity of kind Address that is a child of User([email protected])

The key of the user is

User([email protected])

the key of the company is

User([email protected])\Company(1)

and the key of the two addresses are

User([email protected])\Company(1)\Address(1) 
User([email protected])\Company(1)\Address(2)

I'm pretty new to hierarchical databases so I was wondering why the two addresses are persisted/interpreted as children of user instead of descendants of user and children of company. What is the correct hierarchy for a situation like this? Thanks.

A: 

What version of the app engine sdk are you using? On Monday they released a new one that includes lots of fixes for JDO issues. (release notes) Four or five of the fixes have to do with relationships between objects, so it's possible this issue has been either resolved, or broken in a new way :) OTOH, your issue might be related to this open ticket.

I'm pretty new to hierarchical databases so I was wondering why the two addresses are persisted/interpreted as children of user instead of descendants of user and children of company.

The key hierarchy you are seeing is based on Entity Groups. As as far as the datastore is concerned you could have your companies in a different Entity Group than the User, resulting in a key structure like this:

User([email protected])
Company(1)\Address(1) 
Company(1)\Address(2)

The datastore doesn't necessarily know about one to one mappings, or one to many mappings. It just lets you reference keys of other entities however you like. However, the JDO layer automatically puts all entities in a owned relationship into the same entity group, presumably so it can enforce that changes happen in a transactional manner.

With all that being said, your structure looks OK to me. It looks like the JDO layer is just checking for any entity group descendants that are of Kind Address, rather than looking specifically for one that is a direct child of Company.

Peter Recore
Downloading the new SDK (1.2.2) worked. I was previously using 1.2.1 which had the issue/defect. Thanks Peter.
Enrique Anaya