Child - Parent relationship

619 views
Skip to first unread message

Ruslan V

unread,
Feb 24, 2012, 2:42:31 AM2/24/12
to objectify...@googlegroups.com
Dear Objectify-appengine,

I have a question about child - parent entities relationship in the
context of Objectify4.

So in Ofy3 in parent class I used to have @Transient field for
GWT RPC with child and Key<> field that actually goes to Datastore.

My understanding was that Ofy4 has simplified it and there is no
more need for two fields per relationship.

Here is my child

@Entity
public class Person extends DatastoreObject
{
@Index
private String name;

@Index
private String phoneNumber;

@Index
private String email;

@Parent
private Organization organization;
}

but I'm not sure what I should do in parent.

@Entity
public class Organization extends DatastoreObject
{
@Index
private String name;

@Index
private String address;

@Index
private Person contactPerson; // like this ? seems unlikely
}

My understanding is that I should persist Organization first so I
can persist Person which needs valid key of its parent.

But I can't serialize Organization because Obf says there is field
with null-key (which is true).

I tried to mark Organization.contactPerson as @Ignore. I serialize
it but then I can't serialize Person because Objectify says I can't
persist entities from two different groups in one transaction. But
they are not in different entity groups. It's the same group, right?


/Ruslan
/K Vassiliadis ft Marien - Den Efiges Lepto (dub mix) (1.FM - The Chillout Lounge)

Ruslan V

unread,
Feb 24, 2012, 3:35:07 AM2/24/12
to objectify...@googlegroups.com
Thursday, February 23, 2012, 11:42:31 PM, you wrote:

> Dear Objectify-appengine,

> I have a question about child - parent entities relationship in the
> context of Objectify4.

Just to clarify my question I want to say that I don't understand
use-case for @Load in parent class. I can imagine how it works on
fetching. Perhaps it's querying children with its own key. But I don't
understand how @Load on field in parent class would work when I
persist instance of parent class.

/Ruslan
/Leila Pantel - Energia (1.FM - The Chillout Lounge)

Jeff Schnitzer

unread,
Feb 24, 2012, 10:35:53 AM2/24/12
to objectify...@googlegroups.com
On Fri, Feb 24, 2012 at 2:42 AM, Ruslan V <rus...@gmail.com> wrote:
 My  understanding  was  that  Ofy4 has simplified it and there is no
 more need for two fields per relationship.

Correct.
 
 Here is my child

 but I'm not sure what I should do in parent.

Assuming you didn't include @Id fields for brevity (rather than actually missing them), your examples look fine.  That should work.

Otherwise... you need @Id fields.
 
 My  understanding  is  that I should persist Organization first so I
 can persist Person which needs valid key of its parent.

That's an option, or you can allocate the id for the parent using ObjectifyFactory.allocateId() and then save both entities at the same time.
 
 But  I  can't serialize Organization because Obf says there is field
 with null-key (which is true).

I am confused here - do you really mean to use the word serialize?  Can you post the stracktrace?
 
 I  tried  to mark Organization.contactPerson as @Ignore. I serialize
 it  but then I can't serialize Person because Objectify says I can't
 persist  entities  from two different groups in one transaction. But
 they  are not in different entity groups. It's the same group, right?

I am very confused by the use of "serialize" mixed with Objectify.  Please clarify.

Jeff

Jeff Schnitzer

unread,
Feb 24, 2012, 10:40:13 AM2/24/12
to objectify...@googlegroups.com
On Fri, Feb 24, 2012 at 3:35 AM, Ruslan V <rus...@gmail.com> wrote:
Thursday, February 23, 2012, 11:42:31 PM, you wrote:

> Dear Objectify-appengine,

>   I  have  a question about child - parent entities relationship in the
>   context of Objectify4.

Just  to  clarify  my  question  I want to say that I don't understand
use-case  for  @Load  in  parent  class. I can imagine how it works on
fetching. Perhaps it's querying children with its own key. But I don't
understand  how  @Load  on  field  in  parent  class would work when I
persist instance of parent class.

@Load just causes Objectify to load the entity referenced by the key.... on load() operations.  It doesn't affect save() operations at all.

Objectify sees entity references within an entity as keys, and translates them as necessary.  So in your example, Organization.contactPerson (the direct reference to Person is correct) simply gets stored as a Key in the datastore.  If you put @Load on that field, Objectify will fetch the Key value from the datastore when you load().  Otherwise it will be a "partial" entity, a regular entity object whose @Id and @Parent fields are populated but nothing else.

Jeff

Ruslan V

unread,
Feb 24, 2012, 9:28:41 PM2/24/12
to Jeff Schnitzer
Dear Jeff,
Sorry for bad choice of a verb :) By "serialize" I meant "to persist to Datastore".

I posted my entities here 
http://pastebin.com/M9U99KGT 

I was able to persist pair of Organization + Person with following code

            Person senderPerson = new Person("John Doe", "8181234567", "jo...@gmail.com");

            Organization senderOrganization = new Organization("Safeway", "LA");
            Key<Organization> key = ofy.fact().allocateId(Organization.class);
            senderOrganization.setId(key.getId());
            senderPerson.setOrganization(senderOrganization);

            ofy.save(senderPerson);
            ofy.save(senderOrganization);

Person was persisted correctly and I was able to fetch it by calling

            List<Person> peopele = ofy.load().type(Person.class).ancestor(Key.create(Organization.class, 1)).list();

But there is no love with Organization :( When I fetch it by calling

            Organization tmp = ofy.load(Organization.class, 1);

its "contactPerson" field is null and it's empty when I view at the entity in local DataStore viewer.

Is there something I'm missing in definition of Organization ? What would be the type of "contactPerson" in Datastore? Key<Person>?

Thanks!


/Ruslan
/Particles (2007-05-13) Part 2 - Giorgio Viva - Particelle (Proton Radio)

Jeff Schnitzer

unread,
Feb 25, 2012, 10:13:59 AM2/25/12
to objectify...@googlegroups.com
Are you expecting Objectify to maintain both ends of a bidirectional relationship for you, the way that JDO and JPA do?

Objectify doesn't do that.  It's very much what-you-see-is-what's-in-the-datastore, but just smart enough to translate an entity reference into a key reference for you.  If you never set Organization.contactPerson to a value, it will be null.

If I've misunderstood your code... can you post a complete test case that shows what you expect to happen?

Jeff

Ruslan V

unread,
Feb 25, 2012, 3:14:59 PM2/25/12
to Jeff Schnitzer
Dear Jeff,


Saturday, February 25, 2012, 7:13:59 AM, you wrote:


Are you expecting Objectify to maintain both ends of a bidirectional relationship for you, the way that JDO and JPA do?


It depends what you mean by "maintain both ends" :)


Objectify doesn't do that.  It's very much what-you-see-is-what's-in-the-datastore, but just smart enough to translate an entity reference into a key reference for you.  If you never set Organization.contactPerson to a value, it will be null.


Are you talking about setting Organization.contactPerson manually when I persist Organization or when I load it ? I do former but I expected Ofy4 to do latter.

My problem is that "contactPerson" is null in Datastore after I persist Organization.

I can't understand functional purpose of @Load annotation then.

From early discussions about Ofy4 I thought @Load tells Objectify to:

1) translate entity into its key _when persisting_
2) automatically load entity (defined as a class field) assuming that its key stored in Datastore.

In given sample project it doesn't happen or I don't understand how it's supposed to work.


If I've misunderstood your code... can you post a complete test case that shows what you expect to happen?


I uploaded test project here

http://www.box.com/s/i0ft9z5mrx78c8581i83


Thanks a lot for you help :)

/Ruslan
/Mind Over Matter (2012-02-25) Part 1 - Embliss - Mind Over Matter #039 (Proton Radio)

Ruslan V

unread,
Feb 25, 2012, 3:21:50 PM2/25/12
to Jeff Schnitzer
Dear Ruslan,
I'm ashamed to say but.. OMG ! I forgot to set person on Organization :) I need to take a walk of Marina instead of coding for 16 hours.

Please ignore this email :)

Have a good weekend everyone!
Reply all
Reply to author
Forward
0 new messages