Skip to content

Instantly share code, notes, and snippets.

@doctrinebot
Created December 13, 2015 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doctrinebot/50b8e24061f7718f07c9 to your computer and use it in GitHub Desktop.
Save doctrinebot/50b8e24061f7718f07c9 to your computer and use it in GitHub Desktop.
Attachments to Doctrine Jira Issue DDC-1390 - https://github.com/doctrine/doctrine2/issues/2011
<?php
namespace persistentData\model;
/**
* @MappedSuperclass
*/
abstract class DataObject {
/**
* @Id
* @Column(type="bigint")
* @GeneratedValue
*/
protected $dbID;
/**
* Accessor method for Doctrine proxies to hook in and lazy-load the data object.
* This provides a simple record with accessible properties.
*/
public function & __get($name) {
$referenceHolderVar = $this->$name;
return $referenceHolderVar;
}
/**
* Mutator method for Doctrine proxies to hook in and lazy-load the data object.
* This provides a simple record with accessible properties.
*/
public function __set($name, $value) {
$this->$name = $value;
}
/**
* __isset method for Doctrine proxies to hook in and lazy-load the data object.
* This provides a simple record with accessible properties.
*/
public function __isset($name) {
return isset ($this->$name);
}
/**
* __unset method for Doctrine proxies to hook in and lazy-load the data object.
* This provides a simple record with accessible properties.
*/
public function __unset($name) {
unset ($this->$name);
}
}
<?php
namespace persistentData\model\core;
use \persistentData\model\DataObject;
use \DateTime;
/**
* @Entity
* @Table(indexes={@index(name="Run_timestamp_idx", columns={"timestamp"})})
*/
class Run extends DataObject {
/**
* This timestamp is set once and never modified until the run is eventually deleted.
* It serves to identify the run during its lifetime, regardless of any recomputations made
* to the results produced by it. From a data modeling perspective this is a candidate
* key.
*
* @Column(type="datetime")
*/
protected $timestamp;
/**
* @Column(type="boolean")
*/
protected $isClosed;
/**
* @OneToOne(targetEntity="persistentData\model\core\invoiceCreator\InvoiceCreatorResult", inversedBy="run", cascade={"persist", "remove", "detach"})
* @JoinColumn(name="invoiceCreatorResult_dbID", referencedColumnName="dbID")
*/
protected $invoiceCreatorResult;
/**
* @OneToOne(targetEntity="persistentData\model\core\commissionNoteCreator\CommissionNoteCreatorResult", inversedBy="run", cascade={"persist", "remove", "detach"})
* @JoinColumn(name="commissionNoteCreatorResult_dbID", referencedColumnName="dbID")
*/
protected $commissionNoteCreatorResult;
/**
* @OneToOne(targetEntity="persistentData\model\export\consumerInvoiceExporter\ConsumerInvoiceExporterResult", inversedBy="run", cascade={"persist", "remove", "detach"})
* @JoinColumn(name="consumerInvoiceExporterResult_dbID", referencedColumnName="dbID")
*/
protected $consumerInvoiceExporterResult;
public function __construct(DateTime $timestamp, $isClosed = false) {
$this->timestamp = $timestamp;
$this->isClosed = $isClosed;
}
}
?>
<?php
namespace persistentData\model\core;
use \persistentData\model\DataObject;
use \persistentData\model\versioning\DataVersion;
use \DateTime;
/**
* Ideally, this class would be modeled as a mapped superclass. Unfortunately, Doctrine 2 mandates that mapped superclasses
* must have only unidirectional relationships. Therefore we have to model this class as a regular entity, so that we can have full
* cascading delete support when deleting a data version, using the bidirectional relationship to the data version.
*
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="doctrineTypeDiscriminator", type="string", length=64)
* @DiscriminatorMap({"invoiceCreatorResult" = "persistentData\model\core\invoiceCreator\InvoiceCreatorResult",
* "commissionNoteCreatorResult" = "persistentData\model\core\commissionNoteCreator\CommissionNoteCreatorResult",
* "consumerInvoiceExporterResult" = "persistentData\model\export\consumerInvoiceExporter\ConsumerInvoiceExporterResult"})
*/
abstract class Result extends DataObject {
/**
* This is a purely informative value that can be displayed to the user. It is set to the time the result was created.
*/
protected $timestamp;
/**
* @ManyToOne(targetEntity="persistentData\model\versioning\DataVersion", inversedBy="results")
* @JoinColumn(name="dataVersion_dbID", referencedColumnName="dbID")
*/
protected $dataVersion;
public function __construct(DateTime $timestamp, DataVersion $dataVersion) {
$this->timestamp = $timestamp;
$this->dataVersion = $dataVersion;
}
}
?>
<?php
namespace persistentData\model\core\invoiceCreator;
use \persistentData\model\versioning\DataVersion;
use \persistentData\model\core\Result;
use \Doctrine\Common\Collections\ArrayCollection;
use \DateTime;
/**
* @Entity
*/
class InvoiceCreatorResult extends Result {
/**
* @OneToOne(targetEntity="persistentData\model\core\Run", mappedBy="invoiceCreatorResult")
*/
protected $run;
/**
* @OneToMany(targetEntity="persistentData\model\core\invoiceCreator\Invoice", mappedBy="invoiceCreatorResult", cascade={"persist", "remove", "detach"})
*/
protected $invoices;
public function __construct(DateTime $timestamp, DataVersion $dataVersion) {
parent::__construct($timestamp, $dataVersion);
$this->invoices = new ArrayCollection();
}
}
?>
<?php
namespace persistentData\model\core\commissionNoteCreator;
use \persistentData\model\versioning\DataVersion;
use \persistentData\model\core\Result;
use \Doctrine\Common\Collections\ArrayCollection;
use \DateTime;
/**
* @Entity
*/
class CommissionNoteCreatorResult extends Result {
/**
* @OneToOne(targetEntity="persistentData\model\core\Run", mappedBy="commissionNoteCreatorResult")
*/
protected $run;
/**
* @OneToMany(targetEntity="persistentData\model\core\commissionNoteCreator\CommissionNote", mappedBy="commissionNoteCreatorResult", cascade={"persist", "remove", "detach"})
*/
protected $commissionNotes;
public function __construct(DateTime $timestamp, DataVersion $dataVersion) {
parent::__construct($timestamp, $dataVersion);
$this->commissionNotes = new ArrayCollection();
}
}
?>
<?php
namespace persistentData\model\export\consumerInvoiceExporter;
use \persistentData\model\core\Result;
/**
* @Entity
*/
class ConsumerInvoiceExporterResult extends Result {
/**
* @OneToOne(targetEntity="persistentData\model\core\Run", mappedBy="consumerInvoiceExporterResult")
*/
protected $run;
}
?>
<?php
namespace persistentData\model\versioning;
use \persistentData\model\DataObject;
use \Doctrine\Common\Collections\ArrayCollection;
use \DateTime;
/**
* @Entity
* @Table(indexes={@index(name="DataVersion_timestamp_idx", columns={"timestamp"})})
*/
class DataVersion extends DataObject {
/**
* @Column(type="datetime")
*/
protected $timestamp;
/**
* @ManyToMany(targetEntity="persistentData\model\versioning\InputComponentDataVersion", inversedBy="dataVersions")
* @JoinTable(name="DataVersion_inputComponentDataVersions",
* joinColumns={@JoinColumn(name="dataVersion_dbID", referencedColumnName="dbID")},
* inverseJoinColumns={@JoinColumn(name="inputComponentDataVersion_dbID", referencedColumnName="dbID")})
*/
protected $inputComponentDataVersions;
/**
* @OneToMany(targetEntity="persistentData\model\core\Result", mappedBy="dataVersion")
*/
protected $results;
public function __construct(DateTime $timestamp) {
$this->timestamp = $timestamp;
$this->inputComponentDataVersions = new ArrayCollection();
$this->results = new ArrayCollection();
}
}
?>
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\UnitOfWork;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1390
*/
class DDC1390Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
$classes = array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1390RelatedBase'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1390Related'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1390Entity'),
);
try {
$this->_schemaTool->createSchema($classes);
} catch(\Exception $ignored) {
}
}
public function testIssue()
{
$related = new DDC1390Related;
$entity = new DDC1390Entity;
$entity->related = $related;
$related->entity = $entity;
$this->_em->persist($entity);
$this->_em->flush();
$this->_em->clear();
//$entity = $this->_em->getReference(__NAMESPACE__ . "\DDC1390Entity", $entity->dbId); //proxy or not makes no difference
$dql = "SELECT a FROM " . __NAMESPACE__ . "\DDC1390Entity a WHERE a.dbId = ?1";
$entity = $this->_em->createQuery($dql)->setParameter(1, $entity->dbId)->getSingleResult();
$this->assertNotNull($entity->related);
$this->assertEquals($related->dbId, $entity->related->dbId);
}
}
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorMap({"a" = "DDC1390Related"})
*/
abstract class DDC1390RelatedBase extends DDC1390Object
{
}
/**
* @Entity
*/
class DDC1390Related extends DDC1390RelatedBase
{
/**
* @OneToOne(targetEntity="DDC1390Entity", mappedBy="related")
*/
protected $entity;
}
/**
* @Entity
*/
class DDC1390Entity extends DDC1390Object
{
/**
* @OneToOne(targetEntity="DDC1390Related", inversedBy="entity", cascade={"persist", "remove", "detach"})
* @JoinColumn(name="related_dbId", referencedColumnName="dbId")
*/
protected $related;
}
/**
* @MappedSuperclass
*/
abstract class DDC1390Object
{
/**
* @Id @GeneratedValue @Column(type="integer")
* @var int
*/
protected $dbId;
public function & __get($name)
{
$referenceHolderVar = $this->$name;
return $referenceHolderVar;
}
public function __set($name, $value)
{
$this->$name = $value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment