title: Symfony DDD + Event Sourcing work with related object
body: <p>I use for my project boilerplate: <a href="https://github.com/jorge07/symfony-4-es-cqrs-boilerplate" rel="nofollow noreferrer">https://github.com/jorge07/symfony-4-es-cqrs-boilerplate</a></p>
  
  <p>I have some problems with save and fetch object with related field, but some example:</p>
  
  <ul>
  <li>User</li>
  <li>Stream</li>
  </ul>
  
  <p>Stream has owner User, so mapping:</p>
  
  <p>stream</p>
  
  <pre><code>    &lt;entity name="App\Infrastructure\Stream\Query\Projections\StreamView" table="streams"&gt;
          &lt;id name="uuid" type="uuid_binary" column="uuid"/&gt;
          (...)
          &lt;many-to-one field="user" target-entity="App\Infrastructure\User\Query\Projections\UserView" inversed-by="streams"&gt;
              &lt;join-column nullable="false" referenced-column-name="uuid" /&gt;
          &lt;/many-to-one&gt;
      &lt;/entity&gt;
  </code></pre>
  
  <p>user</p>
  
  <pre><code>    &lt;entity name="App\Infrastructure\User\Query\Projections\UserView" table="users"&gt;
          &lt;id name="uuid" type="uuid_binary" column="uuid"/&gt;
          (...)
          &lt;one-to-many field="streams" target-entity="App\Infrastructure\Stream\Query\Projections\StreamView" mapped-by="user"&gt;
          &lt;/one-to-many&gt;
      &lt;/entity&gt;
  </code></pre>
  
  <p>I want to create new stream, related to User. So, I create CreateStreamCommand and Handler, like this:</p>
  
  <pre><code>    public function __invoke(CreateStreamCommand $command): void
      {
          $stream = $this-&gt;streamFactory-&gt;register($command-&gt;uuid, $command-&gt;user, $command-&gt;parameters);
  
          $this-&gt;streamRepository-&gt;store($stream);
      }
  
      public function __construct(StreamFactory $streamFactory, StreamRepositoryInterface $streamRepository)
      {
          $this-&gt;streamFactory    = $streamFactory;
          $this-&gt;streamRepository = $streamRepository;
      }
  </code></pre>
  
  <p>register method from StreamFactory</p>
  
  <pre><code>    public function register(UuidInterface $uuid, UserViewInterface $user, Parameters $parameters): Stream
      {
          return Stream::create($uuid, $user, $parameters);
      }
  </code></pre>
  create method from Stream
  
  <pre><code>    public static function create(UuidInterface $uuid, UserViewInterface $user, Parameters $parameters): self
      {
          $stream = new self();
  
          $stream-&gt;apply(new StreamWasCreated($uuid, $user, $parameters));
  
          return $stream;
      }
  </code></pre>
  
  <p>And StreamWasCreated Event</p>
  
  <pre><code>    public function __construct(UuidInterface $uuid, UserViewInterface $user, Parameters $parameters)
      {
          $this-&gt;uuid         = $uuid;
          $this-&gt;user         = $user;
          $this-&gt;parameters   = $parameters;
      }
  
      /**
       * @throws \Assert\AssertionFailedException
       */
      public static function deserialize(array $data): self
      {
          Assertion::keyExists($data, 'uuid');
          Assertion::keyExists($data, 'user');
          Assertion::keyExists($data, 'parameters');
  
          return new self(
              Uuid::fromString($data['uuid']),
              $data['user'],
              Parameters::fromArray($data['parameters'])
          );
      }
  
      public function serialize(): array
      {
          return [
              'uuid'          =&gt; $this-&gt;uuid-&gt;toString(),
              'user'          =&gt; $this-&gt;user,
              'parameters'    =&gt; $this-&gt;parameters-&gt;toArray()
          ];
      }
  
  </code></pre>
  
  <p>At this step I don't serialize user, and everything is fine. But... When I want to get this Stream record, I see error: </p>
  
  <pre><code>PHP Fatal error:  Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Argument 2 passed to App\Domain\Stream\Event\StreamWasCreated::__construct() must implement interface App\Domain\User\Query\Projections\UserViewInterface, array given, called in /app/src/Domain/Stream/Event/StreamWasCreated.php on line 51 in /app/src/Domain/Stream/Event/StreamWasCreated.php:32
  Stack trace:
  #0 /app/src/Domain/Stream/Event/StreamWasCreated.php(51): App\Domain\Stream\Event\StreamWasCreated-&gt;__construct(Object(Ramsey\Uuid\Uuid), Array, Object(App\Domain\Stream\ValueObject\Parameters))
  #1 /app/vendor/broadway/broadway/src/Broadway/Serializer/SimpleInterfaceSerializer.php(58): App\Domain\Stream\Event\StreamWasCreated::deserialize(Array)
  #2 /app/vendor/broadway/event-store-dbal/src/DBALEventStore.php(234): Broadway\Serializer\SimpleInterfaceSerializer-&gt;deserialize(Array)
  #3 /app/vendor/broadway/event-store-dbal/src/DBALEventStore.php(93): Broadway\EventStore\Dbal\DBALEventStore-&gt;deserializeEvent(Array)
  #4 /app/vendor/broadway/broadway/s in /app/src/Domain/Stream/Event/StreamWasCreated.php on line 32
  </code></pre>
  
  <p>I checked second argument, and it is empty array. So I think, problem is in unserialize event data.</p>
  
  <p>So my second try was serialize User object, but then I can't save Stream object, because doctrine thinks user is new object and try to cascade persist.</p>
  
  <p>What is the propper way to work with relationship?</p>
  
  <p>Sorry my english ;)</p>