M
M
Max2016-09-09 23:15:56
MySQL
Max, 2016-09-09 23:15:56

What is the correct way to make a 1:M relationship in an aggregate when using DDD?

Tell me how to properly organize a one-to-many relationship in the Aggregate between entities in ORM (for example, in Doctrine 2).
Let's take an example: there is a Rule ( Rule ) and Violation ( Violation ).
It is obvious that there can be no Violation without a Rule. Rule is an Aggregate Root, i.e. we will access Violation only through Rule.
The question is, how to make a relationship here?
Options:

  • 1:M Bidirectional, where the foreign key `rule_id` will be in the `violations` table.
  • 1:M Unidirectional via table binding , but in this case there will be three tables: `rules`, `violations`, `rule_violations`.

And, most importantly, what will the Violation entity look like - will we pass `$ruleId` to the constructor, or will Violation know nothing about Rule?
First option
class Violation
{
    public function __construct(ViolationId $vid, RuleId $rid, /* other parameters /*)
}

Second
class Violation
{
    public function __construct(ViolationId $vid, /* other parameters /*)
}

If it is correct to store the ruleId in the Violation entity, then how to do the mapping in the ORM, because Doctrine works with relationship objects, and not with simple integers.
Thanks

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vicom, 2016-09-10
@vicom

rewrite the question in Russian, please, what

organize a one-to-many relationship in an Aggregate
(there is the concept of Aggregation, but I hear about Aggregates for the first time)
be accessible
(a song without words, a night without sleep..)
..or I'm dullness and all these are terms from an area that I haven't heard too much about
. I initially read this and think the UML metamodel immediately
% public%, explain who is in the woods, and who is for firewood, I just woke up? )

G
GrizliK1988, 2016-09-15
@GrizliK1988

You can read about setting up Doctrine in relation to DDD here: https://leanpub.com/ddd-in-php. On the whole, a very useful book.

M
Maxim, 2016-09-15
@sggr

Why do you need interger? Why do you need to pass an ID to the constructor? This is DDD, you work with objects and their behavior, not properties of objects.
I.e

<?php
class Violation
{
    private $id;
    private $rules;
    public function __construct(ViolationID $vid, array $rules = []) {
        $this->id = $vid;
        $rules = $rules;
    }
    
    public function addRule(Rule $rule) {
        $this->rules[] = $rule;
        return $this;
    }

    public function deleteRule(Rule $rile)...
    public function getRules()...
    ...
}

class Rule
{
    private $id;
    private $violation;
    public function __construct(RuleID $rid, Violation $violation) {
        $this->id = $rid;
        $this->violation = $violation;
    }
    ...
}

There should be no problems with mapping, I will give an example in yaml and recommend using external mapping when using DDD and doctrine.
Core\Violation:
  type: entity
  table: violation
  repositoryClass: InfrastructureBundle\Repository\PersistViolationRepository
  oneToMany:
    rules:
      cascade: [ "persist", "remove" ]
      targetEntity: Core\Rule
      mappedBy: violation
      orphanRemoval: true

Core\Rule:
  type: entity
  table: rule
  repositoryClass: InfrastructureBundle\Repository\PersistRuleRepository
  manyToOne:
    violation:
      targetEntity: Core\Violation
      inversedBy: rules
      joinColumn:
        name: violation_id
        referencedColumnName: id

UPD: I danced from the fact that one violation contains several rules. As I understand it, you have the opposite, but it does not change the essence.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question