On 12 Mar 2010, at 05:45, Jeff Schnitzer wrote:
How, in Twig, do you rename a field?

I'm glad you brought this up. I've found simple renames are better handled at the low level - no need to rehydrate them into instances just to rename a property.

But for typesafe changes large or small Twig supports data migration in a much safer, more flexible way than Objectify. Read on for details.

Objectify lets you import data from a variety of historical formats;
as you load and save data it will naturally be transformed in format:

class Person {
   @Id Long id;
   int age;
   @AlsoLoad("name") String fullName;
}

Cool, the @AlsoLoad is quite a neat feature. Although very limited to simple naming changes and nothing structural. All this is based on a dangerous assumption that you can modify "live" data in place. Hardly bullet proof.

The Twig solution is to create a new version of the type (v2) and process your changes while leaving the live data completely isolated and safe. Then after you have tested your changes you bump up the version number of your live app.

So basically:

1 - Create your new class PersonNew and set its version to 2

        @Version(2)
        class PersonNew {
                 int age;
                String fullName;
        }

2 - Configure the "Kind name" to be the same e.g. "P" (short kind names save DS space)

3 - Load your old Person instances and for each store a new PersonNew instance.

        Your data is now upgraded.

4 - Now you can just replace Person with PersonNew in your code and deploy a new version.

5 - Test the version. This crucial step is not possible with Objectifies solution.

6 - Only when you are happy your changes are correct make the new version live. The new data version will be used and you can delete your old data when you want.

So you see the Twig method of data migration is much safer than Objectifies. It has the following advantages:

1 - You don't eve have a "half-updated" schema
2 - Tt works for major structural changes rather than just trivial field renames.
3 - You can test the new data structure before going live
4 - You can revert back to you old data structure

The versions remain completely separate. Modifying live data in place gives me heart pains.


Now, assume that the user has queries like:

Query<Person> q = ofy.query(Person.class).filter("age >", 65);

Does this query still work in your system?  If so: After a few
renames, how many queries will you be running?  Can you do batch gets
on their ids?  I mean, after you implement batch gets, of course

What is with your obsession with batch gets? I understand they are central in Objectify because you are always loading keys. As I said already - even though this is not as essential in Twig it will be added to a new load command.

Versions are an ugly solution to this problem and they make a giant
mess out of the datastore.

I certainly wouldn't feel comfortable re-factoring my live data without testing it. Having a new version in the datastore is a lot safer than modifying "in place"

How, in Twig, do you make an entity cached?  If it's in your docs, it
is not easy to find.  The Objectify version:

Oops I didn't post the CookBook page in the end. Rest assured it is a trivial addition and I'll update the docs.

It is also often better to cache above the data layer - hardly the killer feature you claim.

Maybe you're right, and we'll see a giant land rush for OR support.
Except that Twig has supported OR queries for quite some time, and it
still hasn't been getting traction.

No, ORs were just added last week :)

Again, it is not my intention to say this feature is inherently wrong
or bad - but that it's not the great revolution that you make it out
to be.  It comes with a cost which the Objectify developers are not
currently willing to pay.

I don't blame you. It was a lot of effort to get right and it works very elegantly without the need for bytecode enhancement or dynamic proxies.

You seem to have an odd definition of Plain Old Java Object.  POJOs
can be copied, created, cloned, whatever.  You can have two of them in
memory with the same id.

Of course, but a POJO is not something that comes with a list of requirements. I guess the level of "plainess" can vary :)

This is actually pretty core to the philosophy of Objectify:  We hate
magic.  We're pretty resistant to features that are not transparent,
and when we do implement features that are magical (like @Embedded),
we document the hell out of it.

I think you hit the nail on the head there Jeff. This is the key difference in philosophies I think. Objectify prefers to keep itself simple even if the developer needs to do more work. Twig prefers to move complexity into the framework - at the cost of making the framework more complex internally (the API remains simple).

A example of this is Twigs feature:

        command.ensureUniqueKey()

Which does a check for an existing natural key before possibly clobbering data.

I assume this would be against the Objectify philosophy because it can be coded manually. I believe that the framework should encapsulate these best practices and make them as easy as possible

Although I do appreciate Objectifies simplicity, really.


Hollow, stateful entities with lifecycles are pretty magical.
Cascading loads and saves are pretty magical.  POJOs and Keys are
simple.

There really is nothing magical about an uninitialised instance. Sounds like you are just on a witch hunt.

John

--
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-j...@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