Doctrine Tips’n’Tricks
(Ilya Antipenko, Grossum)
HOW TO ADD RELATIONSHIP FROM INVERSED SIDE?
• User YML config contains:
WWW.GROSSUM.COM SYMFONY CAFÉ KYIV
HOW TO ADD RELATIONSHIP FROM INVERSED SIDE?
• What will we get in profile table?
• Why? Doctrine documentation: – Doctrine will only check the owning side of an association for changes. – Changes made only to the inverse side of an association are ignored. Make sure
to update both sides of a bidirectional association (or at least the owning side, from Doctrine’s point of view)
WWW.GROSSUM.COM
HOW TO FIX THIS BEHAVIOR?
WWW.GROSSUM.COM
HOW TO REMOVE ITEM FROM ONE-TO-MANY COLLECTION?
WWW.GROSSUM.COM
HOW TO REMOVE ITEM FROM ONE-TO-MANY COLLECTION?
WWW.GROSSUM.COM
o We should use “orphan removal” pattern to remove item from collection
INHERITANCE
• Mapped Superclasses • Single Table Inheritance • Class Table Inheritance
WWW.GROSSUM.COM
INHERITANCE. MAPPED SUPERCLASSES.
• Abstract • Unidirectional relationships only => One-To-Many are not possible • Many-To-Many associations are only possible if the mapped
superclass is only used in exactly one entity at the moment.
WWW.GROSSUM.COM
INHERITANCE. SINGLE TABLE INHERITANCE.
• All classes of hierarchy are mapped to a single table • All fields, added to hierarchy entity, will be added to this single table
– Employee entity extended by Person
WWW.GROSSUM.COM
INHERITANCE. SINGLE TABLE INHERITANCE.
• After execute code:
• Table “person_single_table” contain two records for Employee and
Person entities:
WWW.GROSSUM.COM
INHERITANCE. SINGLE TABLE INHERITANCE.
• This strategy is very efficient for querying across all types in the hierarchy or for specific types.
• No table joins are required, only a WHERE clause listing the type identifiers. In particular, relationships involving types that employ this mapping strategy are very performant.
• Otherwise Doctrine CANNOT create proxy instances of this entity and will ALWAYS load the entity eagerly.
WWW.GROSSUM.COM
INHERITANCE. CLASS TABLE INHERITANCE.
• Several tables. One table for base entity and tables for each child entity.
WWW.GROSSUM.COM
INHERITANCE. CLASS TABLE INHERITANCE.
• After execute code:
• Table “person_joined”:
• Table “employee_joined”:
WWW.GROSSUM.COM
INHERITANCE. CLASS TABLE INHERITANCE.
• This strategy inherently requires multiple JOIN operations to perform just about any query which can have a negative impact on performance.
• Doctrine CANNOT create proxy instances of this entity and will ALWAYS load the entity eagerly.
WWW.GROSSUM.COM
COMPOSITE AND FOREIGN KEYS AS PRIMARY KEY
• Only allowed on Many-To-One or One-To-One associations. • Set a key associationKey: with the field name of the association in
YAML.
• 3 USE-CASES: – Dynamic Attributes – Simple Derived Identity – Join-Table with Metadata
WWW.GROSSUM.COM
Composite and Foreign Keys as Primary Key DYNAMIC ATTRIBUTES
ArticleAttribute: type: entity id: article: associationKey: true attribute: type: string fields: value: type: string manyToOne: article: targetEntity: Article inversedBy: attributes
Article: type: entity id: id: type: integer generator: strategy: AUTO oneToMany: targetEntity: ArticleAttribute mappedBy: article indexBy: attribute cascade: - all
Usage: class Article { … public function addAttribute($name, $value) { $this->attributes[$name] = new ArticleAttribute($name, $value, $this); } ... }
WWW.GROSSUM.COM
Composite and Foreign Keys as Primary Key SIMPLE DERIVED IDENTITY
• Sometimes you have the requirement that two objects are related by a One-To-One association and that the dependent class should re-use the primary key of the class it depends on.
• We encounter problems with SonataORMAdminBundle
WWW.GROSSUM.COM
User: type: entity id: id: type: integer generator: strategy: AUTO
Address: type: entity id: user: associationKey: true oneToOne: user: targetEntity: User
Composite and Foreign Keys as Primary Key JOIN-TABLE WITH METADATA
Order: type: entity id: id: type: integer generator: strategy: AUTO manyToOne: targetEntity: Customer oneToMany: targetEntity: OrderItem mappedBy: order
Product: type: entity id: id: type: integer generator: strategy: AUTO fields: name: type: string price: type: decimal
OrderItem: type: entity id: order: associationKey: true product: associationKey: true manyToOne: order: targetEntity: Order product: targetEntity: Product fields: amount: type: integer
WWW.GROSSUM.COM
THANKS! ILYA ANTIPENKO Company: Grossum E-mail: [email protected]
WWW.GROSSUM.COM SYMFONY CAFÉ KYIV
Examples seen in presentation can be found here: github.com/aivus/doctrine-tips-n-tricks