Scott: Nacho is the author of SimpleDS. Schema migration is something that Hibernate and RDBMSes actually do rather poorly. The typical process is to prepare a series of scripts (ALTER TABLE and then any relevant data transmogrification), shut down the application, run the scripts, then bring up new code that understands the new schema. Hibernate may help provide the scripts, but it won't prevent your downtime.
With large data volumes and significant changes, this process could take a very very long time. The schemaless nature of AppEngine makes migration both easier and harder. Any entity can have any shape, but there are no bulk operations. Furthermore, iterating through your dataset and resaving each entity is a *very slow* operation. Batch jobs on my entities (which have very few indexes) convert less than 100 instances per second. Want to convert 1 million entities? Nearly 3 hours. 10 million? 100 million? The math is easy. We designed the Objectify schema migration tools with the assumptions: 1) You have vast quantities of data 2) The data is changing rapidly 3) Any amount of downtime is unacceptable All transformations within a single entity are pretty easy and straightforward using @AlsoLoad (on a field, lets you load the old name as well as the new) or on a method parameter (lets you obtain the raw data as whatever format you need, munge it, and save it to whatever set of fields you care). Condensing multiple entities into a single entity is also fairly straightforward using @PostLoad and @PrePersist. I'll provide an example if you want. Splitting apart one entity into multiple is by far the hardest transformation, and there isn't any one solution that works for everyone. However, I have done it. Here is one strategy: ---- Starting Entity ---- class Person { @Id Long id; String addressStreet; String addressCity; } Goal: Create an Address entity and add a foreign key reference in Person. ---- Translating Entity ---- class Address { @Id Long id; String street; String city; } class Person { @Id Long id; @LoadOnly String addressStreet; @LoadOnly String addressCity; Key<Address> address; @PrePersist void onSave() { if (addressStreet != null || addressCity != null) { Address addy = new Address(addressStreet, addressCity); address = ObjectifyService.begin().put(addy); } } } You might also need to implement the getAddressStreet() and getAddresCity() methods with a check to the address Key and a load of the Address object. It's somewhat convoluted, but it does work. Another alternative, which gets rid of the complicated getAddressStreet() implementation is to perform the conversion onLoad(): class Person { @Id Long id; @LoadOnly String addressStreet; @LoadOnly String addressCity; Key<Address> address; @PostLoad void onLoad) { if (addressStreet != null || addressCity != null) { Address addy = new Address(addressStreet, addressCity); address = ObjectifyService.begin().put(addy); ObjectifyService.begin().put(this); } } } It really depends on the shape of your data and your query profile - if your app reads a *lot* of entities, you might find the performance profile of convert-on-save to be better. Keep in mind that this type of conversion is a "worst case scenario". Most other schema migrations are fairly simple. Jeff -- 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.