DDD: how to implement correctly with JPA / Hibernate entity relation?

If we follow the principles of DDD, one common root should only have links (by id) to another aggregate root (s).

Example:

// Product Aggregate root
class Product { 

   // References to categories Aggregate Roots (to ids)
   Set<Long> categoryIds;
}

But how can this be achieved with JPA / Hibernate? In jpa, if we want to have, for example, a OneToMany relationship, we defined it as follows:

// Product Aggregate root
class Product { 

   // Holds category aggregate roots
   @OneToMany(mappedBy = "", cascade = CascadeType.ALL)
   Set<Category> categories;
}

Thus, the JPA approach will contain its own aggregate category roots, which is not recommended in DDD.

How would you design a relationship with JPA, but to comply with DDD principles?

PS: I was thinking of creating a categoriesstring type property and listing a comma-separated category identifier, but is there a better solution?

+4
3

, , :

@Entity
public class Product {

    @Id
    @GeneratedValue
    private int id;

    @OneToMany
    @JoinTable
    private Set<Category> categories;

    // constructor, getters, setters, etc...
}


@Entity
public class Category {
    @Id
    @GeneratedValue
    private int id;

    // constructor, getters, setters, etc...
}

, :

for (int n = 0; n < 3; ++n) {
    categoryRepository.save(new Category());
}

Set<Category> categories = categoryRepository.findAll();

productRepository.save(new Product(categories));

( , ...) MySQL:

MariaDB [so41336455]> show tables;
+----------------------+
| Tables_in_so41336455 |
+----------------------+
| category             |
| product              |
| product_categories   |
+----------------------+
3 rows in set (0.00 sec)

MariaDB [so41336455]> describe category; describe product; describe product_categories;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
+-------+---------+------+-----+---------+----------------+
1 row in set (0.00 sec)

+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
+-------+---------+------+-----+---------+----------------+
1 row in set (0.00 sec)

+---------------+---------+------+-----+---------+-------+
| Field         | Type    | Null | Key | Default | Extra |
+---------------+---------+------+-----+---------+-------+
| product_id    | int(11) | NO   | PRI | NULL    |       |
| categories_id | int(11) | NO   | PRI | NULL    |       |
+---------------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

, , :

MariaDB [so41336455]> select * from category; select * from product; select * from product_categories;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+
3 rows in set (0.00 sec)

+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

+------------+---------------+
| product_id | categories_id |
+------------+---------------+
|          1 |             1 |
|          1 |             2 |
|          1 |             3 |
+------------+---------------+
3 rows in set (0.00 sec)

, , . - .

+1

. , . :

public class MyProductApplicationService {
    ...
    @Transactional
    public void loadDependentDataAndCarryOutAggregateAction(Long productId, Long categoryId) {

        Product product = productRepository.findOne(productId);
        Category category = categoryRepository.findOne(categoryId);

        product.doActionThatNeedsFullCategoryAndMayModifyProduct(category);
    }
}

, , , :

class Product {

   @OneToMany(mappedBy = "product")
   Set<Category> categories;
}

public class Category {

    @ManyToOne
    @JoinColumn(name = "productid", insertable = false, updatable = false)
    private Product product;
}
0

, . , . . , , , .

, DDD , Google . :

โ€ข ENTITY .

โ€ข . , .

โ€ข AGGREGATE - , ENTITY. , , . , , , AGGREGATE.

โ€ข , AGGREGATE . .

โ€ข AGGREGATE AGGREGATE.

โ€ข AGGREGATE. ( . , , , .)

โ€ข > AGGREGATE, AGGREGATE .

JPA, , :

  1. @Embeddable , .
  2. @OneToMany, @JoinTable .. - , . .
0

Source: https://habr.com/ru/post/1664947/


All Articles