2

enter image description here

My schema will be something similar to the above picture.

I am planning to use Spring data JDBC and found that

If multiple aggregates reference the same entity, that entity can’t be part of those aggregates referencing it since it only can be part of exactly one aggregate.

Following are my questions:

  1. How to create two different aggregates for the above without changing the DB design?
  2. How to retrieve the Order / Vendor list alone? i.e. I don't want to traverse through the aggregate root.
user1862354
  • 117
  • 11

1 Answers1

3

How to create two different aggregates for the above without changing the DB design?

I think you simply have three Aggregates here: Order, Vendor and ProductType. A mental test that I always use is:

If A has a reference to B and I delete an A, should I automatically and without exception delete all Bs referenced by that A? If so B is part of the A Aggregate.

This doesn't seem to be true for any of the relationships in your diagram, so let's go with separate Aggregates for each entity.

This in turn makes each reference in the diagram one between different Aggregates.

As described in "Spring Data JDBC, References, and Aggregates" these must be modelled as ids in your Java code, not as Java references.

class Order {
    @Id
    Long orderid;
    String name;
    String description;
    Instance created;
    Long productTypeId;
}
class Vendor {
    @Id
    Long vid;
    String name;
    String description;
    Instance created;
    Long productTypeId;
}
class ProductType {
    @Id
    Long pid;
    String name;
    String description;
    Instance created;
}

Since they are separate Aggregates each gets it's own Repository.

interface Orders extends CrudRepository<Order, Long>{
}
interface Vendors extends CrudRepository<Vendor, Long>{}
interface ProductTypes extends CrudRepository<ProductType, Long>{}

At this point I think we fulfilled your requirements. You might have to add some @Column and @Table annotations to get the exact names you want or provide a NamingStrategy.

You probably also want some kind of caching for the product types since I'd expect they see lots of reads with only few writes.

And of course you can add additional methods to the repositories, for example:

interface Orders extends CrudRepository<Order, Long>{
    List<Orders> findByProductTypeId(Long productTypeId);
}
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • I am a bit confused. Based on the diagram, there are two "one to many relationships". 1. Between Product type and vendor 2. Between Product type and Order. But the models don't show that relationship. To be more precise, if I delete the product type, I want to delete only the orders but not the vendors – user1862354 Feb 25 '21 at 08:06
  • The relationships are there. Both `Order` and `Vendor` do have a `productTypeId`. – Jens Schauder Feb 25 '21 at 08:10
  • When we want to save Vendor / Order, we need to pass the product type ID. Constraints created in the database will be validated before inserting them. is my understanding correct? When we render the vendor information, we have to retrieve the Product type information for each vendor separately or store the information in the cache. is my understanding correct? – user1862354 Feb 25 '21 at 09:15