Kent Sølvsten wrote:
When using the phrase *some* I was referring to the possibility of lazy
migration.
In revision 1.0.1 we lazily add a property X to entity Foo. Since the
emigration is lazy, instances are only upgraded as they are touched.
So the system may contain some instances of Foo that are migrated to
1.0.1 and some that are not.
Now we deploy release 1.1 (with property Y added to Foo).
This means, that we should migrate 1.0 (add X and Y) and 1.0.1 (add Y)
instances differently.
I believe the easiest way to express that is with
migration.fromVersion("1.0").toVersion("1.0.1").onEntity("Foo").addProperty("X","defaultvalue");
migration.fromVersion("1.0.1").toVersion("1.1").onEntity("Foo").addProperty("Y","defaultvalue");
If we only register toVersion, the system will have to guess correctly
that version 1.0.1 is the next one after 1.0, so that migration-to-1.0.1
and migration-to-1.1 should be performed when touching an 1.0 instance.
With the potentian to guess wrong.
If there's no funky versioning going on this should be simple. We could
also do it like this:
migration.toVersion("1.0.1")
.onEntity("Foo").addProperty("X", "defaultValue")
.toVersion("1.1")
.onEntity("Foo").addProperty("Y","defaultValue");
I.e. just continue with the fluent API, so that the "from" version is
implicitly known.
Another question is how to handle the case where a release contains no
changes to an entity.
In the system above we might have an entity Bar, which has no change in
1.0.1 and gets a new property Z in version 1.1
How should that be handled when 1.0.1 is deployed? When 1.1 is deployed?
One possibility is to perform an "empty" migration from 1.0 to 1.0.1,
doing nothing but bumping the applicationversion number. The easy
solution, but with redundant work, both for the developer and the
entitystore.
That might be expressed as
migration.fromVersion("1.0").toVersion("1.0.1").onEntity("Foo").addProperty("X","defaultvalue");
migration.fromVersion("1.0.1").toVersion("1.1").onEntity("Foo").addProperty("Y","defaultvalue");
migration.fromVersion("1.0.1").toVersion("1.1").onEntity("Bar").addProperty("Z","defaultvalue");
This I would want to express with:
migration.toVersion("1.0.1")
.onEntity("Foo").addProperty("X", "defaultValue")
.toVersion("1.1")
.onEntity("Foo").addProperty("Y","defaultValue")
.onEntity("Bar").addProperty("Z","defaultValue");
If I get a 1.0 "Bar" entity I can then upgrade to "1.1" through the
empty migration for 1.0.1.
With the branch variant Georg described I could do:
migration.toVersion("1.0.1")
.onEntity("Foo").addProperty("X", "defaultValue")
.toVersion("1.1")
.onEntity("Foo").addProperty("Y","defaultValue")
migration.toVersion("1.1")
.onEntity("Foo").addProperty("X", "defaultValue")
.onEntity("Foo").addProperty("Y","defaultValue")
On:
1.0 -> Use ->1.1 rule : Foo.add(x) & Foo.add(y)
1.0.1 -> Use 1.0.1->1.1 rule: Foo.add(y)
If there's no "strangeness" then the previous case could be used.
Another possibility is to accept that not all instances have the correct
application version. Since there is no migration on Bar from 1.0 to
1.0.1, the client may (when 1.0.1 is deployed) receive a mix of 1.0 and
1.0.1 instances of Bar. This should be no problem, since they have the
same set of properties.
Depends on what you mean by "client". The EntityStore will receive mixed
versions, yes, but once it has been loaded in the EntityStore and is
ready to be used by the application it needs to have been upgraded to
the application version.
The goal here is to always shield the application from version
management, so that it can always assume that the entity being used is
up-to-date.
/Rickard
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev