Yep, that defaultFetchGroup worked nicely!  I sent you an email, let
me know if it did not arrive.

On Nov 9, 2:38 pm, bryce cottam <bcot...@gmail.com> wrote:
> hey James,
> I usually do a defaultFetchGroup="true" on my embedded classes ('cause
> I always want them), but this makes it so that the embedded class is
> always loaded.  This generally isn't a problem because embedded values
> are contained in your entities record in the data store.  However,
> there is another approach that you can use to conditionally load your
> embedded (or any other) fields, the @FetchGroup annotation
>
> @FetchGroups({
>     @FetchGroup(name="Member.dataAuditFetchGroup",
> member...@persistent(name="dataAudit")})})
>
> @PersistenceCapable(identityType = IdentityType.APPLICATION)
> public class Member {
>    ...
>   �...@persistent
>   �...@embedded
>    private DataAudit dataAudit;
>
> }
>
> thus, in a query you could use this fetch group whenever doing a query
> where you knew you wanted your embedded field pre-loaded:
> Query q = pm.newQuery(Member.class);
> q.getFetchPlan().addGroup("Member.dataAuditFetchGroup");
> List<Member> result = (List<Member>) q.execute();
>
> this will go fetch all the Member records, and before giving them back
> to you, it will populate the dataAudit field.
> The name of the FetchGroup is arbitrary, I think it must be unique,
> but it doesn't have to have the field you are referring to in the
> name.  You can also specify multiple fields in the FetchGroup.
> I think this is a really nice feature of JDO over JPA.
>
> hope that helps!!
> -bryce
>
>
>
> On Mon, Nov 9, 2009 at 1:29 PM, James H <james.hollier...@gmail.com> wrote:
>
> > Bryce, I tried another use of your "embedded class" related to Audit
> > fields on an Entity.  For consistency in approach to Auditing entity
> > data, typically you would add the following 4 fields to each entity in
> > your design: createBy, createdDate, updatedBy, and updatedDate.  I
> > thought I'd place these 4 fields in an embedded class to be used by
> > every entity as a Best Practice to manage these 4 fields.  But, I
> > noticed when I tried this on the first entity kind it left the embed
> > null after a standard Query.  The code looks like this:
>
> > @PersistenceCapable(identityType = IdentityType.APPLICATION)
> > public class Member {
> >   �...@primarykey
> >   �...@persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
> >    private Key memberId;
> >   �...@persistent
> >    private Key referringMemberId;
> >   �...@persistent
> >    private String memberType;
> >    ...
> >   �...@persistent
> >   �...@embedded
> >    private DataAudit dataAudit;
> > }
>
> > @PersistenceCapable(embeddedOnly="true")
> > public class DataAudit {
> >   �...@persistent
> >    private Key createMemberId;
> >   �...@persistent
> >    private Date createDate;
> >   �...@persistent
> >    private Key updateMemberId;
> >   �...@persistent
> >    private Date updateDate;
>
> >    public DataAudit() throws Exception {
> >        createMemberId = null;
> >        createDate = null;
> >        updateMemberId = null;
> >        updateDate = null;
> >    }
>
> >    // getters/setters
> > }
>
> > Sample query logic for all members:
>
> > List<Member> list = pm.newQuery(Member.class).execute();
>
> > So each Member in the list is valid, except member.dataAudit is null
> > and I assume the query engine would populate dataAudit along with its
> > fields from the query automatically...as in the case with the embeds
> > from your examples.  Any ideas?
>
> > On Nov 5, 1:40 pm, bryce cottam <bcot...@gmail.com> wrote:
> >> here's a really good talk about how objects are mapped into the
> >> BigTable datastore and how relationships are actually represented in
> >> the 
> >> system:http://sites.google.com/site/io/under-the-covers-of-the-google-app-en...
> >> this sort of highlites how relationships actually work in BigTable
> >> (which is quite different than they work in an RDB).
>
> >> here is another one from Max Ross where he advocates denormalization
> >> for query 
> >> optimization:http://code.google.com/events/io/2009/sessions/SofterSideofSchemas.html
> >> he kind of goes into how the BigTable datastore is simply schema-less.
> >>  Very interesting stuff.
>
> >> hope that helps.
> >> -bryce
>
> >> On Thu, Nov 5, 2009 at 12:34 PM, Rusty Wright <rwright.li...@gmail.com> 
> >> wrote:
>
> >> > Good points.  In my case, so far, the copied objects are small and not 
> >> > complicated, which is why my method appealed to me.
>
> >> > I feel like there's some fundamental concept that I'm not getting and it 
> >> > has to do with how objects are mapped onto the Big Table data store.  
> >> > Watching the videos from Google I/O, those guys just wave their hands 
> >> > and make it sound like it's all so easy, if you know what you're doing.
>
> >> > bryce cottam wrote:
> >> >> I don't think that duplicating the whole Department object as a child
> >> >> of a Person is all that good of an idea.  First off, if the Department
> >> >> object gets complicated and has it's own child objects all that data
> >> >> will be living on the Person, which isn't really needed.  The whole
> >> >> reason for the FK style classes is to pull over only those fields you
> >> >> would want to query on when selecting a Person object like:
> >> >> select from Person where department.name == "ABC"
> >> >> (which is something you cannot do otherwise)
>
> >> >> So, I've found that either having a list of Key (or encoded string
> >> >> ids) on a Person instance is usefull (when you are not wanting to
> >> >> query on fields of the Department when selecting a Person,
> >> >> Or having a list of lightweight copies of a Department (as opposed to
> >> >> the whole Department object)
> >> >> It seems very natural to me to determine equality of two persisted
> >> >> objects by comparing their Key instance, rather than simply their
> >> >> name.  For one reason; it's somewhat difficult to ensure uniqueness
> >> >> for arbitrary fields on an object in the GAE unless that fields is
> >> >> being used to create the key (like an email address or something), if
> >> >> you are using auto-generated Keys, this isn't really an option.
>
> >> >> So, assuming you have the lightweight FK style object as a child of
> >> >> the Person class, then when the source of truth changes (i.e. the real
> >> >> Department instance), you'd need to find all lightweight FK style
> >> >> copies of that instance and update them accordingly.  This is part of
> >> >> the whole root of this discussion: how do you do this in a way that
> >> >> minimized code duplication and boilerplate code blocks (like
> >> >> constructors that manually copy fields from getters to setters etc.)
>
> >> >> The solution I've been working with is the ligthweight FK style "copy"
> >> >> of the real instance of an object, and some simple reflection to map
> >> >> fields from the real object to the lightweight FK "copy".
>
> >> >> As far as detachable="true|false" my main concern with that right now
> >> >> is how the GWT RPC serializer handles detachable entities (i.e. it
> >> >> doesn't handle them well).  There are certainly advantages to
> >> >> detaching an object, however, if the updates to the object are
> >> >> happening on the server, then there is no need to detach the object.
>
> >> >> On Thu, Nov 5, 2009 at 1:09 AM, Rusty Wright <rwright.li...@gmail.com> 
> >> >> wrote:
> >> >>> I think this is an important point.  The light bulb went off over my 
> >> >>> head after watching this video.  This is what he calls a property 
> >> >>> list.  For me it was also a good example of how to think about 
> >> >>> denormalizing, which comes up repeatedly.
>
> >> >>> So instead of the usual OO way of thinking of a department etc. 
> >> >>> aggregating people, turn it on its head and look at it as a person has 
> >> >>> a property, which is their department, and in this example, they can 
> >> >>> be in multiple departments so it's a list of departments, a property 
> >> >>> list.  As you point out, the queries for this are slick.  And it 
> >> >>> sounds like you don't even need the list of people in the department; 
> >> >>> it's redundant.
>
> >> >>> I'm still puzzled about what to do when a property value changes; for 
> >> >>> example, suppose the department named the Ministry of Propaganda 
> >> >>> changes its name to the Ministry of Disinformation.  Does the property 
> >> >>> list on Person contain a list of Department objects, or a list of 
> >> >>> Department Key objects?  I'm thinking the former, Department objects.  
> >> >>> If we have the Department class configured with detachable="false", 
> >> >>> each time you fetch a Department object (matching on its name let's 
> >> >>> say), you get a new unparented Department object, which you add to the 
> >> >>> Person's department list, whereupon it becomes parented by Person.  
> >> >>> The fetched Department object is essentially a clone.  (That's 
> >> >>> assuming I understand how it works when you have detachable="false"; 
> >> >>> it's sort of like the singleton pattern.)  As part of fetching the 
> >> >>> cloned Department object, the Department class has a masterKey field, 
> >> >>> type Key, which you set to the Key of the Department in the table, the 
> >> >>> one it was cloned from.  So
> >> > whe
> >> >>> n the Department's name changes, the query to get all its cloned 
> >> >>> Departments could be simple and quick.  But now I'm fuzzy on how you 
> >> >>> change the master Department's name; since it's detachable="false" we 
> >> >>> can't fetch it and update it and save it back, so I guess we have to 
> >> >>> replace it in the master table and then replace all of its clones in 
> >> >>> all Person lists?
>
> >> >>> bryce cottam wrote:
> >> >>>> ah, gottcha, well there is actually a really good google i/o talk on
> >> >>>> using list/collections and how to optimize them. I generally am using
> >> >>>> "owned" lists for smaller collections,and un-owned ones are
> >> >>>> represented by the child object containing an FK type class as a
> >> >>>> "backwards pointer" to the parent.  If I want to get all the children
> >> >>>> for a given parent, I can query "select from Child where parent.id =
> >> >>>> :myParentId".  Of course, the Child.parent field needs to be embedded
> >> >>>> in order to query off it in this manner.  So, in your case I'd imagine
> >> >>>> a Person would be in a handful of Institutions, but an Institution
> >> >>>> could have tons and tons of Person instances in it.  So I'd think
> >> >>>> you'd want to keep the
>
> ...
>
> read more »- Hide quoted text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine for Java" group.
To post to this group, send email to google-appengine-java@googlegroups.com
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to