Transparent Object Persistence (within FLOW3)
Upcoming SlideShare
Loading in...5
×
 

Transparent Object Persistence (within FLOW3)

on

  • 5,789 views

An overview and some details about how object persistence in FLOW3 works internally.

An overview and some details about how object persistence in FLOW3 works internally.

Statistics

Views

Total Views
5,789
Views on SlideShare
4,332
Embed Views
1,457

Actions

Likes
1
Downloads
39
Comments
0

5 Embeds 1,457

http://flow3.typo3.org 1433
http://www.slideshare.net 17
http://www.bertrandkeller.info 5
http://csit.uniud.it 1
http://209.85.129.132 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Transparent Object Persistence (within FLOW3) Transparent Object Persistence (within FLOW3) Presentation Transcript

  • Transparent Object Persistence (within FLOW3) Karsten Dambekalns <karsten@typo3.org> Inspiring people to share Samstag, 16. Mai 2009
  • “DDD persistence” Domain Models encapsulate behavior and data Concerned about the problem – only Infrastructure is of no relevance Unfortunately you need to be aware of the infrastructure at some point – at least a little Inspiring people to share Samstag, 16. Mai 2009
  • Entities Identity is important Are not defined by their attributes Examples could be... • Projects • Developers Inspiring people to share Samstag, 16. Mai 2009
  • Value objects Have no indentity Their value is of importance Are interchangeable Examples could be... • Colors • Numbers • Tags in Forge Inspiring people to share Samstag, 16. Mai 2009
  • Aggregates Cluster associated objects Have a boundary and a root The root is a specific entity References from outside point to the root An example for an aggregate: • Project Inspiring people to share Samstag, 16. Mai 2009
  • Repositories Provide access to entities (and aggregates) Allow to find a starting point for traversal Persisted objects can be searched for Queries can be built in various ways Handle storage of additions and updates Inspiring people to share Samstag, 16. Mai 2009
  • A Domain Model Project Repository Project Developer SVN twitter Account Account Inspiring people to share Samstag, 16. Mai 2009
  • A Domain Model Project Repository it Project Repos Developer SVN twitter Account Account Inspiring people to share Samstag, 16. Mai 2009
  • A Domain Model Project Repository it Project Repos Developer SVN twitter Account Account Inspiring people to share Samstag, 16. Mai 2009
  • A Domain Model Project Repository it Project Repos Developer SVN twitter Account Account Inspiring people to share Samstag, 16. Mai 2009
  • A Domain Model Project Repository it Project Repos Developer Aggre- gates SVN twitter Account Account Inspiring people to share Samstag, 16. Mai 2009
  • A Domain Model Developer SVN twitter Account Account Inspiring people to share Samstag, 16. Mai 2009
  • Using FLOW3... You just implement the model No need to care about persisting your model FLOW3 handles this for you – transparently Even a Repository only needs little work Define relevant metadata in the source file using annotations Inspiring people to share Samstag, 16. Mai 2009
  • @nnotations used Inspiring people to share Samstag, 16. Mai 2009
  • @nnotations used @entity Inspiring people to share Samstag, 16. Mai 2009
  • @nnotations used @entity @valueobject Inspiring people to share Samstag, 16. Mai 2009
  • @nnotations used @entity @valueobject @var Inspiring people to share Samstag, 16. Mai 2009
  • @nnotations used @entity @valueobject @var @transient Inspiring people to share Samstag, 16. Mai 2009
  • @nnotations used @entity @valueobject @var @transient @uuid Inspiring people to share Samstag, 16. Mai 2009
  • @nnotations used @entity @valueobject @var @transient @uuid @identity Inspiring people to share Samstag, 16. Mai 2009
  • @nnotations used @entity @valueobject @var @transient @uuid @identity @lazy Inspiring people to share Samstag, 16. Mai 2009
  • Persistence Manager Mostly invisible to developers Manages additions of and updates to objects Concerned only about objects in repositories Collects objects and hands over to backend Allows for objects being persisted at any time Automatically called to persist at end of script run Inspiring people to share Samstag, 16. Mai 2009
  • Simplified stack SQLite PgSQL MySQL ... Inspiring people to share Samstag, 16. Mai 2009
  • Simplified stack PDO ... SQLite PgSQL MySQL ... Inspiring people to share Samstag, 16. Mai 2009
  • Simplified stack TYPO3 Content Repository PDO ... SQLite PgSQL MySQL ... Inspiring people to share Samstag, 16. Mai 2009
  • Simplified stack FLOW3 Persistence TYPO3 Content Repository PDO ... SQLite PgSQL MySQL ... Inspiring people to share Samstag, 16. Mai 2009
  • Simplified stack Application Application FLOW3 Persistence TYPO3 Content Repository PDO ... SQLite PgSQL MySQL ... Inspiring people to share Samstag, 16. Mai 2009
  • Simplified stack FLOW3 Persistence Persistence TYPO3 CR Backend Inspiring people to share Samstag, 16. Mai 2009
  • TYPO3 CR FLOW3 Inspiring people to share Samstag, 16. Mai 2009
  • Transparent persistence Explicit support for Domain-Driven Design Class Schemata are defined by the Domain Model class • No need to write an XML or YAML schema definition • No need to define the database model and object model multiple times at different places Automatic persistence in the JSR-283 based Content Repository Legacy data sources can be mounted Inspiring people to share Samstag, 16. Mai 2009
  • Query Factory Creates a query for you Decouples persistence layer from backend Must be implemented by backend API with one method: • public function create($className); Inspiring people to share Samstag, 16. Mai 2009
  • Query objects Represent a query for an object type Allow criteria to be attached Must be implemented by backend Simple API • execute() • matching() • equals(), lessThan(), ... • ... Inspiring people to share Samstag, 16. Mai 2009
  • Object reconstitution When fetching objects the content repository looks for matching nodes The nodes are mapped to objects by a data mapper Reconstitution • does not call __construct() • restores all non-transient properties • reinjects dependencies (skips constructor arguments) Inspiring people to share Samstag, 16. Mai 2009
  • Object reconstitution public function map(F3PHPCRNodeIteratorInterface $nodes) { $objects = array(); foreach ($nodes as $node) { $object = $this->mapSingleNode($node); $this->persistenceManager->getSession()->registerReconstitutedObject($object); $objects[] = $object; } return $objects; } F3TYPO3CRFLOW3PersistenceDataMapper Inspiring people to share Samstag, 16. Mai 2009
  • Object reconstitution $explodedNodeTypeName = explode(':', $node->getPrimaryNodeType()->getName(), 2); $className = str_replace('_', '', $explodedNodeTypeName[1]); $classSchema = $this->persistenceManager->getClassSchema($className); $objectConfiguration = $this->objectManager->getObjectConfiguration($className); $object = $this->objectBuilder->createEmptyObject($className, $objectConfiguration); $this->identityMap->registerObject($object, $node->getIdentifier()); $this->objectBuilder->reinjectDependencies($object, $objectConfiguration); $this->thawProperties($object, $node, $classSchema); $object->FLOW3_Persistence_memorizeCleanState(); F3TYPO3CRFLOW3PersistenceDataMapper Inspiring people to share Samstag, 16. Mai 2009
  • Object reconstitution public function createEmptyObject($objectName, F3FLOW3ObjectConfiguration $objectConfiguration) { $className = $objectConfiguration->getClassName(); if (!in_array('F3FLOW3AOPProxyInterface', class_implements($className))) { throw new F3FLOW3ObjectExceptionCannotReconstituteObject('Cannot create empty instance of the class quot;' . $className . 'quot; because it does not implement the AOP Proxy Interface.', 1234386924); } $object = unserialize('O:' . strlen($className) . ':quot;' . $className . 'quot;:0:{};'); $object->FLOW3_AOP_Proxy_setProperty('objectFactory', $this->objectFactory); $object->FLOW3_AOP_Proxy_setProperty('objectManager', $this->objectManager); $object->FLOW3_AOP_Proxy_declareMethodsAndAdvices(); return $object; } F3FLOW3ObjectBuilder Inspiring people to share Samstag, 16. Mai 2009
  • Lazy Loading Loading a full object tree makes sense – or not It does most of the time If your domain model has small aggregates eager loading makes sense If you have expensive to create objects or a lot of smaller ones you don’t always need, lazy loading helps Example: displaying a list of projects doesn’t need the projects details, just the names Inspiring people to share Samstag, 16. Mai 2009
  • Lazy Loading Ideally you would not think about lazy loading beyond the addition of the @lazy annotation In practice you need to be aware of some technical issues In place of the real object you get a proxy, so • you can’t use it at type hinted places • pass it around without some thinking Using it otherwise works as expected After first use the proxy will be completely gone Inspiring people to share Samstag, 16. Mai 2009
  • The LazyLoadingProxy public function _loadRealInstance() { $realInstance = $this ->F3_FLOW3_Persistence_LazyLoadingProxy_population ->__invoke(); $this ->F3_FLOW3_Persistence_LazyLoadingProxy_parent ->FLOW3_AOP_Proxy_setProperty( $this->F3_FLOW3_Persistence_LazyLoadingProxy_propertyName, $realInstance ); return $realInstance; } F3FLOW3PersistenceLazyLoadingProxy Inspiring people to share Samstag, 16. Mai 2009
  • $dataMapper = $this; // make available to closure... $objectStorage = new F3FLOW3PersistenceLazyLoadingProxy( $parent, $propertyName, function() use ($proxyNode, $dataMapper) { $objectStorage = new SplObjectStorage(); $itemNodes = $proxyNode->getNodes(); foreach ($itemNodes as $itemNode) { $objectNode = $itemNode->getNode('flow3:object'); if ($objectNode->getPrimaryNodeType()->getName() === F3TYPO3CRFLOW3PersistenceBackend::NODETYPE_OBJECTPROXY) { $object = $dataMapper->mapObjectProxyNode($objectNode); } else { $object = $dataMapper->mapSingleNode($objectNode); } $objectStorage->attach($object); } return $objectStorage; } ); F3TYPO3CRFLOW3PersistenceDataMapper Inspiring people to share Samstag, 16. Mai 2009
  • Node structure PHP has more data structures than a content repository, e.g. • JSR-283 defines multi-valued properties without keys and without stable ordering • Arrays in PHP have keys and order that are stable and might be important for your code Thus we do some more mapping to node structures Inspiring people to share Samstag, 16. Mai 2009
  • Inspiring people to share Samstag, 16. Mai 2009
  • Inspiring people to share Samstag, 16. Mai 2009
  • Inspiring people to share Samstag, 16. Mai 2009
  • Inspiring people to share Samstag, 16. Mai 2009
  • Inspiring people to share Samstag, 16. Mai 2009
  • Questions! Inspiring people to share Samstag, 16. Mai 2009
  • Inspiring people to share Samstag, 16. Mai 2009
  • Links FLOW3 http://flow3.typo3.org/ TYPO3CR http://forge.typo3.org/projects/show/package-typo3cr JSR-283 http://jcp.org/en/jsr/detail?id=283 Inspiring people to share Samstag, 16. Mai 2009
  • Samstag, 16. Mai 2009
  • Flickr photo credits: megapixel13 (barcode), rmrayner (ring), Ducatirider (grapes), Here’s Kate (book shelf) Pumpkin pictures: http://ptnoticias.com/pumpkinway/ Inspiring people to share Samstag, 16. Mai 2009