> After numerous exchanges with João via private e-mail, I am finally
> using this new communication channel, as it was suggested some time
> ago.
Great! Thanks Damián.
> I was wondering how hard would it be to handle several Fénix instances
> in the same JVM process. That would be most useful for the work I'm
> doing around domain object replication.
By multiple Fénix instances, I suppose that you mean having more than
one domain model and transactional system (connected to a given
database) working at the same time in the same process, but not in the
same way as is done by Tomcat, for instance, where you have different
classloaders that isolate the various applications from one another,
right?
You want to have code that handles simultaneously instances of both
domain models, is that it?
I haven't thought much about this, but from the top of my head it
doesn't seem very easy to do.
Just to make sure that I understood you correctly, you would like to be
able to initialize the FenixFramework more than once, with different
Config instances, each one corresponding to a different domain model and
database. To be able to distinguish among the various initializations,
we could pass an id to the initialize method. Something along the lines
of:
Config config1 = new Config() {{
domainModelPath = "/domain1.dml";
dbAlias = "//localhost:3306/db1";
dbUsername = "db1User";
dbPassword = "db1Pass";
rootClass = App1.class;
}};
FenixFramework.initialize("ctxt1", config1);
Config config2 = new Config() {{
domainModelPath = "/domain2.dml";
dbAlias = "//localhost:3306/db2";
dbUsername = "db2User";
dbPassword = "db2Pass";
rootClass = App2.class;
}};
FenixFramework.initialize("ctxt2", config2);
But how would you use this, then?
Would you have a transaction for each DB? I imagine that the we could
create a transaction for a given id, such as
@Atomic(context = "ctxt1")
void m() {
// do something that accesses stuff in db1
}
but probably you would want to access entities that come from different
DBs within the same transaction, right?
That means that probably you want transactions to be independent of the
FenixFramework's initializations made before, and we would know which DB
to use from the classes that we are using, assuming that the set of
classes is disjoint among the various domain models.
But if I recall correctly from our previous emails, both of your domain
models will have the same classes (more or less), meaning that you would
not know, from the classes alone, from which DB you should load them.
Once we have objects from different DBs, I imagine that it would be
possible for us to know which DB to use when writing the changes to an
object, if we kept track of which DB each object came from. It may not
be easy to do, but it may be possible (I don't know, I would have to
think much more about this).
But, what would happen if an object from DB1 was connected to an object
from DB2? That should not be possible, right? But then, the framework
would have to detect those cases and prevent them...
Also, what about new objects? Where would we write them?
This was just me "thinking out loud", and I must confess that I don't
have it much clear in my mind, yet. Do you have any clearer ideas of
how things should work?
Wouldn't it be much easier to have two independent JVM processes
communicating between them? How would that be harder than your
suggestion? Can you make a sketch of code for both approaches?
Comments/ideas from anyone else are welcomed...
--
João Cachopo
> We've already had a lengthy discussion about that with Joao; Here's
> the relevant part
Meanwhile, since this email that Stephane included in his message, I've
added to the Fenix Framework the TxIntrospector interface that helps in
solving some of the problems that were being discussed here. I believe
that Damián and Stephane are using this new interface now to capture
changes made in one server, so that they may reapply them in another
server.
I would like to add, as a followup to what I wrote before:
> This is what we do on a daily-basis in the Fénix web application.
>
> Most of the times that the DML file describing the domain model changes,
> we need to transform the data in the DB representing our domain entities
> to become in sync with the latest DML.
>
> Currently, we transform the domain entities via SQL scripts that we run
> on each deploy. You can see examples of those in subdirectories of
>
> https://fenix-ashes.ist.utl.pt/open/trunk/fenix/etc/database_operations/
>
> I don't like this solution, though, and it will become more difficult to
> use when we have multiple versions of the data on the database.
Yesterday I talked with Luis Cruz (I believe that he is reading this
also) again about this same subject and we are more or less coming to
the conclusion that this approach will not work much longer.
As the schema of the DB becomes more complex and farther away from the
traditional relational schema, it becomes harder to change manually.
But I think that continuing to refrain from adding new features to the
Fenix Framework to remain within the comfort zone of the relational
approach is not worth it. We have many things planned or in development
that are continuously set back because of the database. So, I think
that it is time to move on and leave behind the relational schema.
This means that we have to deal with the changes in the persistent data,
when the code changes, entirely at the Java level, rather than at the DB
level.
Best regards,
--
João Cachopo
You want to have code that handles simultaneously instances of both
domain models, is that it?
I haven't thought much about this, but from the top of my head it
doesn't seem very easy to do.
Just to make sure that I understood you correctly, you would like to be
able to initialize the FenixFramework more than once, with different
Config instances, each one corresponding to a different domain model and
database. To be able to distinguish among the various initializations,
we could pass an id to the initialize method. Something along the lines
of:
But how would you use this, then?
Would you have a transaction for each DB? I imagine that the we could
create a transaction for a given id, such as
@Atomic(context = "ctxt1")
void m() {
// do something that accesses stuff in db1
}
but probably you would want to access entities that come from different
DBs within the same transaction, right?
That means that probably you want transactions to be independent of the
FenixFramework's initializations made before, and we would know which DB
to use from the classes that we are using, assuming that the set of
classes is disjoint among the various domain models.
But if I recall correctly from our previous emails, both of your domain
models will have the same classes (more or less), meaning that you would
not know, from the classes alone, from which DB you should load them.
Mmmh, not sure what would be the exact semantics of that, transactionally speaking. Simultaneous access to Domain Objects coming from differents DBs in the same transaction is not required. We could have the following patten:
@Atomic(context = "ctxt1")void m() {
// do something that accesses stuff in db1
return usefulValues
}
That means that probably you want transactions to be independent of the
FenixFramework's initializations made before, and we would know which DB
to use from the classes that we are using, assuming that the set of
classes is disjoint among the various domain models.
This was just me "thinking out loud", and I must confess that I don't
have it much clear in my mind, yet. Do you have any clearer ideas of
how things should work?
Wouldn't it be much easier to have two independent JVM processes
communicating between them? How would that be harder than your
suggestion? Can you make a sketch of code for both approaches?