Hi.
I have a problem I´m not able to find a solution for. Hopefully someone on this
list can help.
Background:
In our system we have a use case where some entities need to be initialized
(created or updated) at the startup of the system. Mainly this happens at the
first startup, but also sometimes the entities needs to be updated with new
values for some properties. To support this usecase I need to be able to query
the entitystore to find out if the entities I wan´t to create already exist or
not. My initial solution for this was to add a mixin with a property i called
"readableIdentifier" to the entity-types that I needed to be able to bootstrap.
I then do a conditional create based on wether or not I can find an entity with
the correct "readableIdentifier". This kind of works, but the conditional
create seems quite brittle as I haven´t found a way to make the
"readableIdentifier" unique. So then the other day I was reading some API, and
I found that doing unitofwork.create(MyEntity.class, "myReadableIdentifier")
probably was a better way to support my use case. Why I didn´t see this before
is a bit annoying, but anyway, now I´m in the situation where I want´t to
change my code to use this new approach but I also have to support the
datastore we have in test already.
My initial thoughts was to use the Migration api to change the identity of the
entities in question. Since EntityMigrationOperation doesn´t support changing
the identiy of an entity (which makes sense since we also need to change all
references to the entity), I decided to use an implementation of
MigrationOperation. The problem is I cannot figure out how to do the actual
implementation. The problem is that the upgrade-method on MigrationOperation
only accept StateStore and Migrator as parameters. These interfaces doesn´t
give me any way to query the entitystore. So it seem impossible to me to find
the entities I want to change. I´ve tried several approaches, one of which are
casting the StateStore to an EntityStore and then visit all EntitiesState´s and
do some conditionals there. For example:
private static class MigrateReadableIdentifierOperation implements
MigrationOperation {
...
@Override
public void upgrade(StateStore stateStore, Migrator migrator)
throws IOException {
Set<EntityState> entitiesToMigrate = new
HashSet<EntityState>();
EntityStore entityStore = (EntityStore)stateStore;
entityStore.visitEntityStates(new
EntityStore.EntityStateVisitor() {
@Override
public void visitEntityState(EntityState
entityState) {
if(shouldMigrate()) {
entitiesToMigrate.add(entityState);
}
}
}, /* How do i get the module????*/ );
.... Migrate entityStates
}
}
The problem here is that I cannot find a way to get a reference to the Module
I´m running in. Since the MigrationOperation isn´t injected it doesn´t seem
like it´s possible to get a reference to any application component. So my
questions are:
1. Is using unitOfWork.create(MyEntity.class, "myReadableIdentifier") a good
solution to support my use case?
2. Is there an easy way to change the identity of an entity that already exist
in the EntityStore?
3. How do you use the MigrationOperation to update entities when you don´t know
the id of the entities until runtime? Specifically; How do you get access to
application components from an instance of a MigrationOperation?
Best regards
Webstep AS
RONNIE NESSA | Senior Consultant
Mob : +47 970 69 512 | [email protected]
www.webstep.no
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev