views:

626

answers:

2

Hi am i'm trying the new Java support for google app engine, and i am trying to make a persistency layer for all my objects. I am trying to model a friend connection but am running into problems. I use JPA to persist the objects and define my persistency objects with JPA annotations.

My idea was to do the following:

User Object:

@Entity
public class User  {

@Column(name="user_id")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") 
private String id;

@OneToMany(cascade={CascadeType.ALL},mappedBy="invitee")
private List<Connection> IncConnections;

@OneToMany(cascade={CascadeType.ALL},mappedBy="initiator")
private List<Connection> OutConnections;
}

.

@Entity
public class Connection {

@Column(name="connection_id")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") 
private String id;

@ManyToOne(cascade={CascadeType.ALL})
User initiator;

@ManyToOne(cascade={CascadeType.ALL})
User invitee;
}

But when i try this i get the error: App Engine ORM does not support multiple parent key provider fields

So does anyone have an other idea how to model a friend system without using multiple parent keys?

Hope someone can help!

+1  A: 

I've never actually used the google app engine for a project yet but the first thing you need to understand about its persistence is that it is not a Relational Database. I believe it uses a key value store.

So you sort of need to think of persistence in a different way when using the app engine.

From the documentation:

The following features of the JPA interface are not supported by the App Engine implementation:

  • Owned many-to-many relationships, and unowned relationships. You can implement unowned relationships using explicit Key values, though type checking is not enforced in the API.
  • "Join" queries. You cannot use a field of a child entity in a filter when performing a query on the parent kind. Note that you can test the parent's relationship field directly in query using a key.
  • Aggregation queries (group by, having, sum, avg, max, min)
  • Polymorphic queries. You cannot perform a query of a class to get instances of a subclass. Each class is represented by a separate entity kind in the datastore.

http://code.google.com/appengine/docs/java/datastore/usingjpa.html

Peter D
suprisingly, GAP supports JPA, although it runs on bigtable.
Andreas Petersson
I know it does, but you cannot use joins on tables. Therefore you must rethink your model.
Peter D
Yeah i know this, i dont have very much experience with persistency yet so i really could use an idea to how to approach this model.
+2  A: 

In general, you will have to maintain any relationships yourself with GAE. The best tools that GAE provides for this are documented in their section on Unowned Relationships. In particular, I believe the section on "Many-to-Many" relationships is relevant.

From the examples, it seems that you still have to do most of the work of maintaining referential integrity yourself. Because these are likely to be in separate entity groups, you will likely also have to have a significant amount of code to deal with potentially broken relationships.

jsight