Cloning an Aggregate

My need is to clone an aggregate, because the user wants to use a
source AR as template and change the copy.

I want: use the evenstream of one aggregate to build a second.
I think I do this by:

1. issuing a CloneAR(sourceId, newId) command
2. subcassing GenericEventSourcingRepository#clone(sourceId, newId) to
read every Event from sourceAggregate
3. adding a Copyable interface on each Event
4. e.copy() it in #clone(sourceId, newId)
5. saving the new AR

a) Is this a good plan?
b) would it be an interesting contribution as an axon feature?

cheers ro

What does a “clone” mean? Is it that you copy each of the past events on A into B?
I never came across a usecase where I needed to do so. What are you trying to achieve?

Why would you want to keep the history of thing A in the copy, thing
B? I can understand why you would want to copy the values over to B
but not the history.

@Allard: I think the use case is generic. User wants to have a copy of
AR1 to change some Properties
In my case it is a nutrition-label calculator. A Baker has a RecipeA
and he wants to try a variation, RecipeB

Copy&Paste is a common use case for user interaction.

@Per: RecipeB can share the event-stream of RecipeA, why should I
forget where it is coming? From a higher level, it is true that
RecipeB shares the same genealogy of RecipeA.

I see the event history as a possibility to extract historical
information and to use it in a context-aware app. For example to
prefill a field. The late John McCarty experimented with this in
Elephant 2000.

"Elephant source programs may not need data structures, because they
can refer directly to the past. Thus a program can say that an airline
passenger has a reservation if he has made one and hasn't cancelled
it."
http://www-formal.stanford.edu/jmc/elephant/elephant.html

A event-stream never forgets. We should use this!

ro

Hi Roland,

it is possible to implement something like this. Your events would need a copy-constructor that allows you to attach events to another aggregate (and with another sequence number as well).

However, to me, it does come across as “faking history”. To copy a recipe, I would add that as a fact to the event store. So the first event of RecipeB would be a RecipeCopiedEvent that contains a reference to RecipeA (identifier only, of course). To create the recipe, you would copy all the information from recipe A. In the end, the copy is that fact that really occurred. Copying the history will make it seem like recipe B was created at the same time as recipe A, but in fact, it wasn’t. It’s all about how to model stuff.

This brings to mind something Eric Evans said during his training: you must fail at least three times to get it right. :wink:

Cheers,

Allard

I see your point, you can't have it as a generic method then. Will
implement it that way.
But, in order to fail a fourth time: could'nt the RecipeCopiedEvent be
a special ReplicaSnapshotEvent?
I think its a snapshot with an extra property
sourceAggregateIdentifer...

no?

You could make it a snapshot. The problem with snapshots is that they should always be a (performance related) replacement of a series of other events. In other words, deleting a snapshot should not alter behavior.

Cheers,

Allard