SlideShare una empresa de Scribd logo
1 de 18
Introduction to ORM Doctrine 2
Object-relational mapping (ORM, O/RM, and O/R mapping) in computer software is a programming technique for converting data between incompatible type systems in object-oriented programming languages.  This creates, in effect, a "virtual object database" that can be used from within the programming language. There are both free and commercial packages available that perform object-relational mapping, although some programmers opt to create their own ORM tools.
Loose coupling: Given two lines of code, A and B, they are coupled when B must change behavior only because A changed. Content coupling (high) is when one module modifies or relies on the internal workings of another module (e.g. accessing local data of another module). Therefore changing the way the second module produces data (location, type, timing) will lead to changing the dependent module.  High cohesion: They are cohesive when a change to A allows B to change so that both add new value. Functional cohesion (best) is when parts of a module are grouped because they all contribute to a single well-defined task of the module Loose coupling and High Coupling
Ways to deal with data coming from Relational DB's: ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Direct SQL:
Ways to achive “Low Cohesion” and “High coupling” Classes.... first approach class Orders { public function __construct($orderId) { $sql = “select  o.order_id,.... from order o  inner join o.order_product op on... Inner join op.product p on... inner join o.customers c on. where o.order_id = $orderId. } } class Customer { public function getFullName(){} public function getRating(){} } Class Product { public function getPrice(){} }
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Ways to achive “Low Cohesion” and “High coupling”
class Order { public function __construct($orderId) { $sql = “select  o.order_id,.... from order o  where o.order_id = $orderId” } public function getOrderProducts() { $sql = “select op.order_product_id,.... from order_product op where order_id = $this->orderId” } public function getCustomer() { $sql = “select c.customer_id,.... from customer c where c.customer_id = $this->customerId” } } Ways to achive “Low Cohesion” and “High coupling”
class Order { public function __construct($orderId) { $sql = “select  o.order_id,.... from order o  where o.order_id = $orderId” } public function getOrderProducts() { $this->_orderProducts = new OrderProductCollection($this->orderId); } public function getCustomer() { $this->_customer = new Customer($this->customerId); } } Or even better... Ways to achive “Low Cohesion” and “High coupling”
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Ways to achive “Low Cohesion” and “High coupling”
$queryBuilder = $em ->createQueryBuilder(); ->select('o') ->from('Entitiesrders', 'o') ->innerJoin('o.ordersProducts', 'op') ->innerJoin('o.customers', 'c') ->where($queryBuilder->expr()->in('o.ordersId', '?1')) ->setMaxResults(1) ->setParameter(1, '5030492') ->getQuery(); $order = $query->getSingleResult(); This will generate an efficent code: SELECT .....  FROM orders o0_  INNER JOIN orders_products o1_ ON o0_.orders_id = o1_.orders_id  INNER JOIN customers c2_ ON o0_.customers_id = c2_.customers_id  WHERE o0_.orders_id IN (?)  LIMIT 1 Ways to achive “Low Cohesion” and “High coupling” Welcome to Doctrine 2: DQL language
[object Object],[object Object],[object Object],[object Object],Doctrine 2
How to access the data: echo  $order->getCustomer()->getFirstName(); echo $order->getCustomer()->getFullName(); echo $order->getAddressDeliveryStreet(); foreach(  $order->getOrdersProducts() as $orderProduct ) { echo $orderProduct->getOrdersProductsId(); echo $orderProduct->getProductName(); } Doctrine create and inject (Hydrate) the data into $order, $customer $orderProducts (collection). We still have decouple and choesive objects Doctrine 2
We sill can do: $queryBuilder = $em ->createQueryBuilder(); ->select('o') ->from('Entitiesrders', 'o'); And access, but sql no as efficent...: “ SELECT o0.... FROM orders o0_ WHERE o0_.orders_id IN (?) LIMIT 1” echo  $order->getCustomer()->getFirstName(); “ SELECT t0.... FROM customers t0 WHERE t0.customers_id = ?” echo $order->getCustomer()->getFullName(); echo $order->getAddressDeliveryStreet(); $orderProducts = $order->getOrdersProducts(); “ SELECT t0... FROM orders_products t0 WHERE orders_id = ?” foreach( $orderProducts as $orderProduct) { echo $orderProduct->getOrdersProductsId(); echo $orderProduct->getProductName(); } Doctrine 2
Also we have magic finder methods throw the repositories: $em->getRepository(“Entitiesrder”)->find() Or ->findByCustomerId() Doctrine 2
We meet the Doctrin Entities... <?php namespace Entities; /** *  @Entity @Table(name=&quot;orders&quot;) */ class Orders {  /** * @Id @Column(type=&quot;integer&quot;, name=&quot;orders_id&quot;) * @GeneratedValue(strategy=&quot;AUTO&quot;) */ private $ordersId; /** * @Column(type=&quot;integer&quot;, name=&quot;customers_id&quot;) */  private $customersId; /** * @ManyToOne(targetEntity=&quot;Customers&quot;) * @JoinColumn(name=&quot;customers_id&quot;, referencedColumnName=&quot;customers_id&quot;) */ private $customers; public function getOrdersId()  { return $this->ordersId; } public function setOrderId($orderId) { $this->ordersId = $ordersId; }  Doctrine 2
They don't follow the Active Record pattern like Zend_Table or Doctrine: “ Active record is an approach to accessing data in a database. A database table or view is wrapped into a class. Thus, an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database. When an object is updated the corresponding row in the table is also updated. The wrapper class implements accessor methods or properties for each column in the table or view.”
Data Mapper The Data Mapper is a layer of software that separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other. With Data Mapper the in-memory objects needn't know even that there's a database present; they need no SQL interface code, and certainly no knowledge of the database schema. (The database schema is always ignorant of the objects that use it.) Since it's a form of Mapper (473), Data Mapper itself is even unknown to the domain layer $order = new Order; $order->setCustomerId(3); $order->setDeliveryAddress('....'); $em->persist($order); $em->flush();
[object Object],[object Object],[object Object],[object Object],[object Object],Next Session....

Más contenido relacionado

La actualidad más candente

WSDL-Design-and-Generation-in-EASparx
WSDL-Design-and-Generation-in-EASparxWSDL-Design-and-Generation-in-EASparx
WSDL-Design-and-Generation-in-EASparx
Frank Ning
 
Ado.net xml data serialization
Ado.net xml data serializationAdo.net xml data serialization
Ado.net xml data serialization
Raghu nath
 

La actualidad más candente (17)

Hibernate
HibernateHibernate
Hibernate
 
Graph db as metastore
Graph db as metastoreGraph db as metastore
Graph db as metastore
 
Jdbc ppt
Jdbc pptJdbc ppt
Jdbc ppt
 
ASP.NET 09 - ADO.NET
ASP.NET 09 - ADO.NETASP.NET 09 - ADO.NET
ASP.NET 09 - ADO.NET
 
Spring framework part 2
Spring framework part 2Spring framework part 2
Spring framework part 2
 
Introduction to JPA (JPA version 2.0)
Introduction to JPA (JPA version 2.0)Introduction to JPA (JPA version 2.0)
Introduction to JPA (JPA version 2.0)
 
Apply hibernate to model and persist associations mappings in document versio...
Apply hibernate to model and persist associations mappings in document versio...Apply hibernate to model and persist associations mappings in document versio...
Apply hibernate to model and persist associations mappings in document versio...
 
WSDL-Design-and-Generation-in-EASparx
WSDL-Design-and-Generation-in-EASparxWSDL-Design-and-Generation-in-EASparx
WSDL-Design-and-Generation-in-EASparx
 
Schema201 webinar
Schema201 webinarSchema201 webinar
Schema201 webinar
 
Introduction to JPA Framework
Introduction to JPA FrameworkIntroduction to JPA Framework
Introduction to JPA Framework
 
JPA Best Practices
JPA Best PracticesJPA Best Practices
JPA Best Practices
 
Entity Persistence with JPA
Entity Persistence with JPAEntity Persistence with JPA
Entity Persistence with JPA
 
Jdbc
JdbcJdbc
Jdbc
 
Dealing with SQL Security from ADO.NET
Dealing with SQL Security from ADO.NETDealing with SQL Security from ADO.NET
Dealing with SQL Security from ADO.NET
 
Jpa 2.1 Application Development
Jpa 2.1 Application DevelopmentJpa 2.1 Application Development
Jpa 2.1 Application Development
 
Lecture17
Lecture17Lecture17
Lecture17
 
Ado.net xml data serialization
Ado.net xml data serializationAdo.net xml data serialization
Ado.net xml data serialization
 

Destacado

Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!
Herman Peeren
 

Destacado (7)

#jd12nl Seblod 2
#jd12nl  Seblod 2#jd12nl  Seblod 2
#jd12nl Seblod 2
 
Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!
 
How Pony ORM translates Python generators to SQL queries
How Pony ORM translates Python generators to SQL queriesHow Pony ORM translates Python generators to SQL queries
How Pony ORM translates Python generators to SQL queries
 
ORM: Object-relational mapping
ORM: Object-relational mappingORM: Object-relational mapping
ORM: Object-relational mapping
 
Object Relational model for SQLIite in android
Object Relational model for SQLIite  in android Object Relational model for SQLIite  in android
Object Relational model for SQLIite in android
 
Python PPT
Python PPTPython PPT
Python PPT
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 

Similar a Doctrine 2 - Introduction

Vpd Virtual Private Database By Saurabh
Vpd   Virtual Private Database By SaurabhVpd   Virtual Private Database By Saurabh
Vpd Virtual Private Database By Saurabh
guestd83b546
 
Php Data Objects
Php Data ObjectsPhp Data Objects
Php Data Objects
hiren.joshi
 
Nhibernatethe Orm For Net Platform 1226744632929962 8
Nhibernatethe Orm For Net Platform 1226744632929962 8Nhibernatethe Orm For Net Platform 1226744632929962 8
Nhibernatethe Orm For Net Platform 1226744632929962 8
Nicolas Thon
 

Similar a Doctrine 2 - Introduction (20)

Agile Data Science 2.0 - Big Data Science Meetup
Agile Data Science 2.0 - Big Data Science MeetupAgile Data Science 2.0 - Big Data Science Meetup
Agile Data Science 2.0 - Big Data Science Meetup
 
JPA 2.0
JPA 2.0JPA 2.0
JPA 2.0
 
Ado.net
Ado.netAdo.net
Ado.net
 
Agile Data Science 2.0
Agile Data Science 2.0Agile Data Science 2.0
Agile Data Science 2.0
 
Agile Data Science 2.0
Agile Data Science 2.0Agile Data Science 2.0
Agile Data Science 2.0
 
Plsql
PlsqlPlsql
Plsql
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in php
 
ADO.NET
ADO.NETADO.NET
ADO.NET
 
Agile Data Science 2.0
Agile Data Science 2.0Agile Data Science 2.0
Agile Data Science 2.0
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Android database tutorial
Android database tutorialAndroid database tutorial
Android database tutorial
 
Agile Data Science
Agile Data ScienceAgile Data Science
Agile Data Science
 
Vpd Virtual Private Database By Saurabh
Vpd   Virtual Private Database By SaurabhVpd   Virtual Private Database By Saurabh
Vpd Virtual Private Database By Saurabh
 
NHibernate
NHibernateNHibernate
NHibernate
 
Linq to sql
Linq to sqlLinq to sql
Linq to sql
 
Php Data Objects
Php Data ObjectsPhp Data Objects
Php Data Objects
 
ADO.NET by ASP.NET Development Company in india
ADO.NET by ASP.NET  Development Company in indiaADO.NET by ASP.NET  Development Company in india
ADO.NET by ASP.NET Development Company in india
 
Jdbc Dao it-slideshares.blogspot.com
Jdbc Dao it-slideshares.blogspot.comJdbc Dao it-slideshares.blogspot.com
Jdbc Dao it-slideshares.blogspot.com
 
Intake 38 data access 5
Intake 38 data access 5Intake 38 data access 5
Intake 38 data access 5
 
Nhibernatethe Orm For Net Platform 1226744632929962 8
Nhibernatethe Orm For Net Platform 1226744632929962 8Nhibernatethe Orm For Net Platform 1226744632929962 8
Nhibernatethe Orm For Net Platform 1226744632929962 8
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 

Doctrine 2 - Introduction

  • 1. Introduction to ORM Doctrine 2
  • 2. Object-relational mapping (ORM, O/RM, and O/R mapping) in computer software is a programming technique for converting data between incompatible type systems in object-oriented programming languages. This creates, in effect, a &quot;virtual object database&quot; that can be used from within the programming language. There are both free and commercial packages available that perform object-relational mapping, although some programmers opt to create their own ORM tools.
  • 3. Loose coupling: Given two lines of code, A and B, they are coupled when B must change behavior only because A changed. Content coupling (high) is when one module modifies or relies on the internal workings of another module (e.g. accessing local data of another module). Therefore changing the way the second module produces data (location, type, timing) will lead to changing the dependent module. High cohesion: They are cohesive when a change to A allows B to change so that both add new value. Functional cohesion (best) is when parts of a module are grouped because they all contribute to a single well-defined task of the module Loose coupling and High Coupling
  • 4.
  • 5. Ways to achive “Low Cohesion” and “High coupling” Classes.... first approach class Orders { public function __construct($orderId) { $sql = “select o.order_id,.... from order o inner join o.order_product op on... Inner join op.product p on... inner join o.customers c on. where o.order_id = $orderId. } } class Customer { public function getFullName(){} public function getRating(){} } Class Product { public function getPrice(){} }
  • 6.
  • 7. class Order { public function __construct($orderId) { $sql = “select o.order_id,.... from order o where o.order_id = $orderId” } public function getOrderProducts() { $sql = “select op.order_product_id,.... from order_product op where order_id = $this->orderId” } public function getCustomer() { $sql = “select c.customer_id,.... from customer c where c.customer_id = $this->customerId” } } Ways to achive “Low Cohesion” and “High coupling”
  • 8. class Order { public function __construct($orderId) { $sql = “select o.order_id,.... from order o where o.order_id = $orderId” } public function getOrderProducts() { $this->_orderProducts = new OrderProductCollection($this->orderId); } public function getCustomer() { $this->_customer = new Customer($this->customerId); } } Or even better... Ways to achive “Low Cohesion” and “High coupling”
  • 9.
  • 10. $queryBuilder = $em ->createQueryBuilder(); ->select('o') ->from('Entitiesrders', 'o') ->innerJoin('o.ordersProducts', 'op') ->innerJoin('o.customers', 'c') ->where($queryBuilder->expr()->in('o.ordersId', '?1')) ->setMaxResults(1) ->setParameter(1, '5030492') ->getQuery(); $order = $query->getSingleResult(); This will generate an efficent code: SELECT ..... FROM orders o0_ INNER JOIN orders_products o1_ ON o0_.orders_id = o1_.orders_id INNER JOIN customers c2_ ON o0_.customers_id = c2_.customers_id WHERE o0_.orders_id IN (?) LIMIT 1 Ways to achive “Low Cohesion” and “High coupling” Welcome to Doctrine 2: DQL language
  • 11.
  • 12. How to access the data: echo $order->getCustomer()->getFirstName(); echo $order->getCustomer()->getFullName(); echo $order->getAddressDeliveryStreet(); foreach( $order->getOrdersProducts() as $orderProduct ) { echo $orderProduct->getOrdersProductsId(); echo $orderProduct->getProductName(); } Doctrine create and inject (Hydrate) the data into $order, $customer $orderProducts (collection). We still have decouple and choesive objects Doctrine 2
  • 13. We sill can do: $queryBuilder = $em ->createQueryBuilder(); ->select('o') ->from('Entitiesrders', 'o'); And access, but sql no as efficent...: “ SELECT o0.... FROM orders o0_ WHERE o0_.orders_id IN (?) LIMIT 1” echo $order->getCustomer()->getFirstName(); “ SELECT t0.... FROM customers t0 WHERE t0.customers_id = ?” echo $order->getCustomer()->getFullName(); echo $order->getAddressDeliveryStreet(); $orderProducts = $order->getOrdersProducts(); “ SELECT t0... FROM orders_products t0 WHERE orders_id = ?” foreach( $orderProducts as $orderProduct) { echo $orderProduct->getOrdersProductsId(); echo $orderProduct->getProductName(); } Doctrine 2
  • 14. Also we have magic finder methods throw the repositories: $em->getRepository(“Entitiesrder”)->find() Or ->findByCustomerId() Doctrine 2
  • 15. We meet the Doctrin Entities... <?php namespace Entities; /** * @Entity @Table(name=&quot;orders&quot;) */ class Orders { /** * @Id @Column(type=&quot;integer&quot;, name=&quot;orders_id&quot;) * @GeneratedValue(strategy=&quot;AUTO&quot;) */ private $ordersId; /** * @Column(type=&quot;integer&quot;, name=&quot;customers_id&quot;) */ private $customersId; /** * @ManyToOne(targetEntity=&quot;Customers&quot;) * @JoinColumn(name=&quot;customers_id&quot;, referencedColumnName=&quot;customers_id&quot;) */ private $customers; public function getOrdersId() { return $this->ordersId; } public function setOrderId($orderId) { $this->ordersId = $ordersId; } Doctrine 2
  • 16. They don't follow the Active Record pattern like Zend_Table or Doctrine: “ Active record is an approach to accessing data in a database. A database table or view is wrapped into a class. Thus, an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database. When an object is updated the corresponding row in the table is also updated. The wrapper class implements accessor methods or properties for each column in the table or view.”
  • 17. Data Mapper The Data Mapper is a layer of software that separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other. With Data Mapper the in-memory objects needn't know even that there's a database present; they need no SQL interface code, and certainly no knowledge of the database schema. (The database schema is always ignorant of the objects that use it.) Since it's a form of Mapper (473), Data Mapper itself is even unknown to the domain layer $order = new Order; $order->setCustomerId(3); $order->setDeliveryAddress('....'); $em->persist($order); $em->flush();
  • 18.