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

          Avi Block created issue -
          Roman S. Borschel made changes -
          Field Original Value New Value
          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....
          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....
          Fix Version/s 2.1 [ 10022 ]
          Benjamin Eberlei made changes -
          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....
          {code}
          class User {
          /**
          * @Column(type="string")
          */
          private $address;

          /**
          * @Column(type="string")
          */
          private $city;

          /**
          * @Column(type="string")
          */
          private $state;
          }
          {code}

          We could have:

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

          It would my life a lot easier....
          Roman S. Borschel made changes -
          Description {code}
          class User {
          /**
          * @Column(type="string")
          */
          private $address;

          /**
          * @Column(type="string")
          */
          private $city;

          /**
          * @Column(type="string")
          */
          private $state;
          }
          {code}

          We could have:

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

          It would my life a lot easier....
          {code}
          class User {
          /**
          * @Column(type="string")
          */
          private $address;

          /**
          * @Column(type="string")
          */
          private $city;

          /**
          * @Column(type="string")
          */
          private $state;
          }
          {code}

          We could have:

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

          It would my life a lot easier....

          ----

          h2. 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).

          h3. 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, ...


          h3. Persisters

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

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


          h3. 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, ...


          h3. 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, ...


          Benjamin Eberlei made changes -
          Link This issue is duplicated by DDC-648 [ DDC-648 ]
          Benjamin Eberlei made changes -
          Fix Version/s 2.x [ 10090 ]
          Fix Version/s 2.1 [ 10022 ]
          Benjamin Eberlei made changes -
          Assignee Roman S. Borschel [ romanb ] Guilherme Blanco [ guilhermeblanco ]
          Benjamin Eberlei made changes -
          Workflow jira [ 10295 ] jira-feedback [ 13835 ]
          Benjamin Eberlei made changes -
          Workflow jira-feedback [ 13835 ] jira-feedback2 [ 15699 ]
          Benjamin Eberlei made changes -
          Workflow jira-feedback2 [ 15699 ] jira-feedback3 [ 17956 ]
          Benjamin Eberlei made changes -
          Link This issue is referenced by DDC-2374 [ DDC-2374 ]
          Benjamin Eberlei made changes -
          Link This issue is duplicated by DDC-2805 [ DDC-2805 ]
          Benjamin Eberlei made changes -
          Link This issue is duplicated by DDC-2804 [ DDC-2804 ]
          Benjamin Eberlei made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Fix Version/s 2.5 [ 10522 ]
          Fix Version/s 2.x [ 10090 ]
          Resolution Fixed [ 1 ]

            People

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

              Dates

              • Created:
                Updated:
                Resolved: