Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-93

It would be nice if we could have support for ValueObjects

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.5
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      class User {
      	/**
      	 * @Column(type="string")
      	 */
      	private $address;
      	
      	/**
      	 * @Column(type="string")
      	 */
      	private $city;
      	
      	/**
      	 * @Column(type="string")
      	 */
      	private $state;
      }
      

      We could have:

      class User {
      	/**
      	 * @Component(class="Address")
      	 */
      	 private $address;
      }
      

      It would my life a lot easier....


      Notes for implementation

      Value objects can come in two forms:

      a) as embedded value objects
      b) as collections of value objects

      An implementation should concentrate on a) first. The following things all concentrate on a).

      DQL Support

      Conditions:

      1. "select f from Foo f where f.embedded.value = ?1" (setParameter(1, $scalarValue))
      2. "select f from Foo f where f.embedded = ?1" (setParameter(1, $embeddedValueObject))

      At least Nr.1 must be possible in a first implementation.

      Selecting:

      1. "select f from Foo f" must explode embedded value objects in the SQL SELECT clause.
      2. "select f.embedded from Foo f" must explode the columns of the embedded object in the SQL SELECT clause.

      At least Nr. 1 must be possible in a first implementation, obviously.

      Components affected (among others): Parser, SqlWalker, ...

      Persisters

      The persisters need to take embedded value objects into account when persisting as well as loading entities.

      Components affected (among others): Persisters, UnitOfWork, ...

      Metadata

      ClassMetadataInfo needs to be extended with a field (probably an array) that contains the mappings of embedded values.
      New annotations as well as XML/YAML elements are needed.

      Components affected (among others): ClassMetadataInfo, AnnotationDriver, YamlDriver, XmlDriver, doctrine-mapping.xsd, ...

      Change Tracking

      If value objects are supposed to be immutable this is easy and might require no or few changes. If, however, we want to track changes in mutable value objects it might get more complicated.

      Components affected (among others): UnitOfWork, ...

        Issue Links

          Activity

          Hide
          Doctrine Bot added a comment -

          A related Github Pull-Request [GH-835] was closed:
          https://github.com/doctrine/doctrine2/pull/835

          Show
          Doctrine Bot added a comment - A related Github Pull-Request [GH-835] was closed: https://github.com/doctrine/doctrine2/pull/835
          Hide
          Doctrine Bot added a comment -

          A related Github Pull-Request [GH-634] was closed:
          https://github.com/doctrine/doctrine2/pull/634

          Show
          Doctrine Bot added a comment - A related Github Pull-Request [GH-634] was closed: https://github.com/doctrine/doctrine2/pull/634
          Hide
          Marco Pivetta added a comment -

          songoko songowan yes please! Especially if you can provide some links/details on what the feature would look like and how it is implemented in JPA/Hibernate.

          Show
          Marco Pivetta added a comment - songoko songowan yes please! Especially if you can provide some links/details on what the feature would look like and how it is implemented in JPA/Hibernate.
          Hide
          songoko songowan added a comment -

          well I can see that much work was done on implementing this feature on https://github.com/doctrine/doctrine2/pull/835#issuecomment-28697601

          However, it seems mapping a collection of value objects won't be supported in this patch. Currently we have to treat them as entities till further notice.

          Should a new issue be opened specifically for mapping a collection of value objects?

          Show
          songoko songowan added a comment - well I can see that much work was done on implementing this feature on https://github.com/doctrine/doctrine2/pull/835#issuecomment-28697601 However, it seems mapping a collection of value objects won't be supported in this patch. Currently we have to treat them as entities till further notice. Should a new issue be opened specifically for mapping a collection of value objects?
          Hide
          Nino Martincevic added a comment -

          @Matthieu

          That's the old question of when a customer is a customer?
          A customer could be:

          • someone who visits the shop ([anonymous] visitor)
          • someone who registers (user)
          • someone who buys something (buyer)
          • in delivery context it's just an address (recipient)
          • in accounting context it's a legal person or company (invoice recipient)

          Guess you wouldn't have separate database entities/tables for all of these roles.

          So, yes. A class could (but doesn't has to) be a VO and an Entity, but only in a different context.
          In most cases it just plays another role. It could be specially factored by a repository
          for a specific use case, having other behaviour than in another.
          E.g. in delivery context it could have more than one address, a private and a delivery one.

          The more we talk about the more we see that the business (language) drives the design of your classes.
          And if it's clear which objects play a role in which context it becomes very clear what
          kind of classes or roles you need. And also that without a bounded context you could never
          answer the question what kind of classes you really need.

          Hope that helps.

          Show
          Nino Martincevic added a comment - @Matthieu That's the old question of when a customer is a customer? A customer could be: someone who visits the shop ( [anonymous] visitor) someone who registers (user) someone who buys something (buyer) in delivery context it's just an address (recipient) in accounting context it's a legal person or company (invoice recipient) Guess you wouldn't have separate database entities/tables for all of these roles. So, yes. A class could (but doesn't has to) be a VO and an Entity, but only in a different context. In most cases it just plays another role. It could be specially factored by a repository for a specific use case, having other behaviour than in another. E.g. in delivery context it could have more than one address, a private and a delivery one. The more we talk about the more we see that the business (language) drives the design of your classes. And if it's clear which objects play a role in which context it becomes very clear what kind of classes or roles you need. And also that without a bounded context you could never answer the question what kind of classes you really need. Hope that helps.

            People

            • Assignee:
              Guilherme Blanco
              Reporter:
              Avi Block
            • Votes:
              40 Vote for this issue
              Watchers:
              37 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: