xmolecules / jmolecules

Libraries to help developers express architectural abstractions in Java code
http://jmolecules.org
Apache License 2.0
1.26k stars 104 forks source link

Nesting of multiple Entities / AggregateRoots? #110

Closed seekM closed 11 months ago

seekM commented 12 months ago

I tried to model a domain using jmolecules and trying to nest multiple Entities resp. AggregateRoots lead me to compilation errors:


Entities example:

public class Foo implements AggregateRoot<Foo, FooId> { ... }
public class Bar implements Entity<Foo, BarId> { ... }
public class Woo implements Entity<Bar, WooId> { ... } // (1)

For (1) I get:

Bound mismatch: The type Bar is not a valid substitute for the bounded parameter <T extends AggregateRoot<T,?>> of the type Entity<T,ID>


AggregateRoots example:

public class Foo implements AggregateRoot<Foo, FooId> { ... }
public class Bar implements Entity<Foo, BarId>, AggregateRoot<Bar, BarId> { ... }  // (2)
public class Woo implements Entity<Bar, WooId> { ... }

For (2) I get:

The interface Entity cannot be implemented more than once with different arguments: Entity<Bar,Bar.BarId> and Entity<Foo,Bar.BarId>


I am wondering if I am doing something wrong in this regard, if this kind of modelling is something which is not allowed / recommended in DDD and hasn't been implemented because of that or if this is maybe something which could be implemented in the future?

If I'm not mistaken the AggregateRoots example could work if Foo referred to Bar by Bar's ID; in this way Bar wouldn't be part of the Foo Aggregate. However, it feels to me that in the Bounded Context I am modelling it doesn't make a lot of sense for Bar to be able to exist without Foo, so I went for the approach shown here (Foo having a direct reference to Bar). I'm happy to share a bit more about the domain I am modelling if this is helpful.

odrotbohm commented 11 months ago

An entity is owned by one aggregate root, as otherwise, the aggregate cannot fulfil its constraining nature. That's is why you declaration of Bar works. Woo is wrong as you need to point it to an owning aggregate, which you don't as Bar is none.

From what you write, it feels like Bar should be its own aggregate and Foo simply refer to it via its identifier or an Association.