Objectiphy
  • Introduction
  • Quick Start
  • Basic Fetching
  • Basic Saving
  • Deleting
  • Mapping Providers
    • Attributes
    • Objectiphy Mapping
    • Doctrine Mapping
  • Defining Relationships
    • One to one
    • One to Many
    • Many to one
    • Many to Many
    • Scalar Joins
  • Query Builder
    • Running a Query
    • Select Queries
    • Update Queries
    • Insert Queries
    • Delete Queries
    • Criteria
      • Operators
      • Filtering by Child Objects
      • Filtering by Aggregates
    • Joins
  • Pagination and Sorting
  • Embedded Value Objects
  • Serialization Groups
  • Late Binding and Lazy Loading
  • Streaming Results
  • Custom Repositories
  • Optimisation
  • Configuration Options
  • Mapping Overrides
  • Caching
  • Comparison with Doctrine
  • Code Generation etc.
  • Troubleshooting
  • Licence, Copyright, Credits
Powered by GitBook
On this page

Was this helpful?

Embedded Value Objects

Value objects represent values that are made up of more than one element, such as addresses or prices. A value object is different from an entity, because an entity has an identity separate from its properties - you can change the value of a property on an entity, but it is still regarded as the same entity. Value objects are essentially immutable - if you were to change the value of a property, the whole object would be regarded as a brand new value. For example, changing the house number of an address object turns it into a completely different address - even if no other properties change. Likewise, changing the currency of a price turns it into a completely different price, even if the numerical part stays the same.

As value objects have no identity separate from their properties, they cannot have a primary key or any single value identifier. Of course you could add an address ID or whatever, and turn it into an entity, but we are assuming here that you don't want to do that, and that your value objects have no identity of their own, and belong to a parent entity as a property. So a Customer entity might have an address property, which is an Address value object that has no ID. It's even possible that Customer has both homeAddress and businessAddress properties, and each of those are different instances of the Address value object class.

In cases like this, the value object fields are typically stored in the same table as the parent entity. If more than one instance of the same type of value object can appear on the parent, each would typically have a prefix on its column names. So an entity like this:

Customer
  ├id
  ├name
  ├homeAddress
  │   ├houseNumber
  │   ├street
  │   ├town
  │   └postcode
  └businessAddress
      ├houseNumber
      ├street
      ├town
      └postcode

...might be stored in a database like this:

customer table:
id
name
home_address_house_number
home_address_street
home_address_town
home_address_postcode
business_address_house_number
business_address_street
business_address_town
business_address_postcode

ie. There is no separate table for storing the address information - it is 'embedded' in the parent.

class Customer
{
    #[Column(isPrimaryKey: true)]
    public int $id;
    
    #[Column]
    public string $name;
    
    #[Relationship(
        childClassName: Address::class,
        relationshipType: 'one_to_one',
        isEmbedded: true,
        embeddedColumnPrefix: 'home_address_'
    )]
    public Address $homeAddress;
    
    #[Relationship(
        childClassName: Address:class,
        relationshipType: 'one_to_one',
        isEmbedded: true,
        embeddedColumnPrefix: 'business_address_'
    )]
    public Address $businessAddress;
}

... and the Address object might look like this (an embedded value object would not have a table defined, as it uses the table of its parent class):

class Address
{
    #[Column]
    public $houseNumber;
    
    #[Column]
    public $street;
    
    #[Column]
    public $town;
    
    #[Column]
    public $postcode;
}
PreviousPagination and SortingNextSerialization Groups

Last updated 2 years ago

Was this helpful?

To tell Objectiphy that a property holds an embedded value object, set the isEmbedded attribute to true on the mapping. If there is a prefix for the column name, you can specify that on the embeddedColumnPrefix attribute of the . For example, our customer entity might look something like this:

Relationship
Relationship mapping