On 2010-04-28 08.19, Niclas Hedhman wrote:
Well, my problem is that I don't have the use-case, and highly
speculative guess work; Entities are inherently mutable, and I like
Values better. So, I think what I am fishing for is
"conversion"-support between entities and values, possibly as
entities->values and values->entitybuilders.
Yes, working with values if you are not in a UoW is better. So we might
want to have a way to "shuffle" entity data into values, but then the
question is what can you do with it? Because typically you need the
logic in the entities to be able to make changes that make sense.
How can we
provide better lazy-loading support for Entitystore implementors?
Implementing some kind of caching helper would be nice. Pretty much all
stores right now would benefit from it.
Yes, I thought we had that already, and can extend it.
Where? Am I missing something?
But lazy-loading is Properties and Values is (AFAIK) not implemented,
mainly due to the JSON serialization strategy, which breaks down for
large (non-association) collections that are seldom accessed. So,
direct support for "append" as well as "get on demand" would be great,
but I know it is non-trivial.
Lazy-loading in properties in entities is implemented in the sense that
the data will not be deserialized until a property is loaded. But the
data for an entity will be loaded in full when it is accessed. However,
this is an implementation detail, and it would be entirely possible to
only load parts of an entity when accessing it, provided that you have
split it up accordingly when storing it.
That's what I did in SiteVision actually, where each mixin was stored
separately. Now that I see that my entities in Streamflow have LOTS of
mixins, that might make more sense actually. But there's always the
issue of performance and overhead in storing/loading data, and there's
no one answer to what is the best I think. "It depends".
What
about the earlier NestedUnitOfWork, can we sort that out? Should we?
I would suggest that we don't do that. It messes things up too much I think.
This is actually strange. If a MemoryEntityStore is created on the
fly, and attached to the underlying UoW, it looks on paper very
straight forward.
Hm... maybe that now when there's no apply(), it could be done more
easily. Have to think about it. Again: what is the usecase though?
I don't know how to "access it", but basically at the API level be
able to ask for an Entity's state at a particular point in time is
what I am looking for. A built-in way for the access, which is either
turned on or off. Then that would probably need support in SPI level.
Why not EventSourcing? Because, although I am convinced that it is
more suitable in many cases, I don't think it will be popular due to
learning curve. People are really used to ORM-like models, and if that
basic understanding is complemented with "Oh, I have automatic history
support without effort!", I think our standing as kick-ass system will
be even higher.
The main reason I can see history being important is actually to support
time, in the sense that Rich Hickey of Clojure describes it. If you have
entities A(v1) and B(v1), and they are in a consistent state in relation
to each other. If I load A(v1) in a UoW and start doing things with, and
at the same time someone else does something to B that changes it to v2,
then when my UoW access B it will be v2, which is not consistent with
A(v1). But I won't see any errors, and my UoW will commit without
errors. In this case I would have wanted B(v1) to be loaded in my UoW,
and upon commit I should have gotten an error since B has progressed to v2.
Aggregates are one way to deal with this, where the aggregate root has a
version which is bumped when B is updated to v2. When I start my UoW I
don't have to care about versions of A and B, instead I just note the
version of the aggregate root R. When committing I check if the version
I had at the start is the same as the current version of R. If it is, I
can commit, if not something within R has changed and I have to start
over. This gives me strong consistency in the context that I am
interested in, and is actually more powerful than what optimistic
concurrency in RDBMS transactions can offer me.
If we have this notion, then there is actually no need to keep version
information in A and B, only in R, because that is what I'll be checking
when committing. I suppose this is similar to what Git does, which keeps
a hash on the tree as a whole. That hash ensures that I cannot make any
changes on the parts if the tree as a whole has moved on.
Does that make sense?
As I mentioned, a broad subject. One area is easily identifiable;
There are many ways to connect separate systems with messages,
synchronous, asynchronous, RPC-like or document-based and so on. Just
like we abstract away the persistence, so that different
implementations can be plugged in after the code is written, I think
we should do the same for messaging. Loads of enterprise systems has
some type of cross-system messaging (often XML (not always SOAP) over
MQ), and we should tick that box in a powerful way.
It seems to me that what we need to do in Qi4j core is to support
EventSourcing, and to allow those events to be stored in services that
implement an SPI. That SPI can then be implemented in a ton of ways, to
cater for various ways of sending those events around.
To handle messaging generally, on a system level, is outside our scope.
That is what ESBs like Camel and Mule does, and I would prefer to leave
it to them.
Then there is in-app events, where EventSourcing may (I need to look
at it closer) be suitable, or may be not. Either way, my guess is that
library is 'good enough' here and don't need an extension SPI.
As above, I can imagine that it would be a good idea to have DomainEvent
as a core concept, with SPI's to support it, but then the nitty gritty
of how those events are handled, pushed and consumed is outside our scope.
Qi4j should deal with everything that an application developer has to
deal with. System level detail should be plugins, and is outside our scope.
/Rickard
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev