[2.0][DDC-144][DDC-113] Fixed.
This commit is contained in:
parent
3d14da4105
commit
30ed439111
9 changed files with 141 additions and 36 deletions
|
@ -16,4 +16,9 @@ class LifecycleEventArgs extends \Doctrine\Common\EventArgs
|
|||
{
|
||||
return $this->_entity;
|
||||
}
|
||||
|
||||
public function getEntityManager()
|
||||
{
|
||||
return $this->_em;
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ class AnnotationDriver implements Driver
|
|||
} else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) {
|
||||
$metadata->isMappedSuperclass = true;
|
||||
} else {
|
||||
throw DoctrineException::classIsNotAValidEntityOrMapperSuperClass($className);
|
||||
throw DoctrineException::classIsNotAValidEntityOrMappedSuperClass($className);
|
||||
}
|
||||
|
||||
// Evaluate DoctrineTable annotation
|
||||
|
|
|
@ -64,7 +64,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
*/
|
||||
private function _getVersionedClassMetadata()
|
||||
{
|
||||
if ($isVersioned = $this->_class->isVersioned) {
|
||||
if ($this->_class->isVersioned) {
|
||||
if (isset($this->_class->fieldMappings[$this->_class->versionField]['inherited'])) {
|
||||
$definingClassName = $this->_class->fieldMappings[$this->_class->versionField]['inherited'];
|
||||
$versionedClass = $this->_em->getClassMetadata($definingClassName);
|
||||
|
@ -125,43 +125,59 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
$idGen = $this->_class->idGenerator;
|
||||
$isPostInsertId = $idGen->isPostInsertGenerator();
|
||||
|
||||
// Prepare statements for all tables
|
||||
$stmts = $classes = array();
|
||||
$stmts[$this->_class->primaryTable['name']] = $this->_conn->prepare($this->getInsertSql());
|
||||
// Prepare statement for the root table
|
||||
$rootClass = $this->_class->name == $this->_class->rootEntityName ?
|
||||
$this->_class : $this->_em->getClassMetadata($this->_class->rootEntityName);
|
||||
$rootPersister = $this->_em->getUnitOfWork()->getEntityPersister($rootClass->name);
|
||||
$rootTableName = $rootClass->primaryTable['name'];
|
||||
$rootTableStmt = $this->_conn->prepare($rootPersister->getInsertSql());
|
||||
if ($this->_sqlLogger !== null) {
|
||||
$sql[$this->_class->primaryTable['name']] = $this->getInsertSql();
|
||||
$sql = array();
|
||||
$sql[$rootTableName] = $rootPersister->getInsertSql();
|
||||
}
|
||||
|
||||
// Prepare statements for sub tables.
|
||||
$subTableStmts = array();
|
||||
if ($rootClass !== $this->_class) {
|
||||
$subTableStmts[$this->_class->primaryTable['name']] = $this->_conn->prepare($this->getInsertSql());
|
||||
if ($this->_sqlLogger !== null) {
|
||||
$sql[$this->_class->primaryTable['name']] = $this->getInsertSql();
|
||||
}
|
||||
}
|
||||
foreach ($this->_class->parentClasses as $parentClassName) {
|
||||
$parentClass = $this->_em->getClassMetadata($parentClassName);
|
||||
$parentPersister = $this->_em->getUnitOfWork()->getEntityPersister($parentClassName);
|
||||
$stmts[$parentClass->primaryTable['name']] = $this->_conn->prepare($parentPersister->getInsertSql());
|
||||
if ($this->_sqlLogger !== null) {
|
||||
$sql[$parentClass->primaryTable['name']] = $parentPersister->getInsertSql();
|
||||
$parentTableName = $parentClass->primaryTable['name'];
|
||||
if ($parentClass !== $rootClass) {
|
||||
$parentPersister = $this->_em->getUnitOfWork()->getEntityPersister($parentClassName);
|
||||
$subTableStmts[$parentTableName] = $this->_conn->prepare($parentPersister->getInsertSql());
|
||||
if ($this->_sqlLogger !== null) {
|
||||
$sql[$parentTableName] = $parentPersister->getInsertSql();
|
||||
}
|
||||
}
|
||||
}
|
||||
$rootTableName = $this->_em->getClassMetadata($this->_class->rootEntityName)->primaryTable['name'];
|
||||
|
||||
|
||||
// Execute all inserts. For each entity:
|
||||
// 1) Insert on root table
|
||||
// 2) Insert on sub tables
|
||||
foreach ($this->_queuedInserts as $entity) {
|
||||
$insertData = array();
|
||||
$this->_prepareData($entity, $insertData, true);
|
||||
|
||||
// Execute insert on root table
|
||||
$stmt = $stmts[$rootTableName];
|
||||
$paramIndex = 1;
|
||||
if ($this->_sqlLogger !== null) {
|
||||
$params = array();
|
||||
foreach ($insertData[$rootTableName] as $columnName => $value) {
|
||||
$params[$paramIndex] = $value;
|
||||
$stmt->bindValue($paramIndex++, $value);
|
||||
$rootTableStmt->bindValue($paramIndex++, $value);
|
||||
}
|
||||
$this->_sqlLogger->logSql($sql[$rootTableName], $params);
|
||||
} else {
|
||||
foreach ($insertData[$rootTableName] as $columnName => $value) {
|
||||
$stmt->bindValue($paramIndex++, $value);
|
||||
$rootTableStmt->bindValue($paramIndex++, $value);
|
||||
}
|
||||
}
|
||||
$stmt->execute();
|
||||
unset($insertData[$rootTableName]);
|
||||
$rootTableStmt->execute();
|
||||
|
||||
if ($isPostInsertId) {
|
||||
$id = $idGen->generate($this->_em, $entity);
|
||||
|
@ -170,9 +186,10 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
|
||||
}
|
||||
|
||||
// Execute inserts on subtables
|
||||
foreach ($insertData as $tableName => $data) {
|
||||
$stmt = $stmts[$tableName];
|
||||
// Execute inserts on subtables.
|
||||
// The order doesn't matter because all child tables link to the root table via FK.
|
||||
foreach ($subTableStmts as $tableName => $stmt) {
|
||||
$data = isset($insertData[$tableName]) ? $insertData[$tableName] : array();
|
||||
$paramIndex = 1;
|
||||
if ($this->_sqlLogger !== null) {
|
||||
$params = array();
|
||||
|
@ -197,7 +214,8 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
}
|
||||
}
|
||||
|
||||
foreach ($stmts as $stmt) {
|
||||
$rootTableStmt->closeCursor();
|
||||
foreach ($subTableStmts as $stmt) {
|
||||
$stmt->closeCursor();
|
||||
}
|
||||
|
||||
|
|
|
@ -168,6 +168,8 @@ class StandardEntityPersister
|
|||
$stmt->bindValue($paramIndex++, $value);
|
||||
}
|
||||
}
|
||||
} else if ($this->_sqlLogger !== null) {
|
||||
$this->_sqlLogger->logSql($this->getInsertSql());
|
||||
}
|
||||
|
||||
$stmt->execute();
|
||||
|
|
|
@ -370,12 +370,6 @@ class UnitOfWork implements PropertyChangedListener
|
|||
* Computes all the changes that have been done to entities and collections
|
||||
* since the last commit and stores these changes in the _entityChangeSet map
|
||||
* temporarily for access by the persisters, until the UoW commit is finished.
|
||||
*
|
||||
* @param array $entities The entities for which to compute the changesets. If this
|
||||
* parameter is not specified, the changesets of all entities in the identity
|
||||
* map are computed if automatic dirty checking is enabled (the default).
|
||||
* If automatic dirty checking is disabled, only those changesets will be
|
||||
* computed that have been scheduled through scheduleForDirtyCheck().
|
||||
*/
|
||||
public function computeChangeSets()
|
||||
{
|
||||
|
@ -579,6 +573,13 @@ class UnitOfWork implements PropertyChangedListener
|
|||
$state = $this->getEntityState($entry, self::STATE_NEW);
|
||||
$oid = spl_object_hash($entry);
|
||||
if ($state == self::STATE_NEW) {
|
||||
if (isset($targetClass->lifecycleCallbacks[Events::prePersist])) {
|
||||
$targetClass->invokeLifecycleCallbacks(Events::prePersist, $entry);
|
||||
}
|
||||
if ($this->_evm->hasListeners(Events::prePersist)) {
|
||||
$this->_evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entry));
|
||||
}
|
||||
|
||||
// Get identifier, if possible (not post-insert)
|
||||
$idGen = $targetClass->idGenerator;
|
||||
if ( ! $idGen->isPostInsertGenerator()) {
|
||||
|
@ -696,7 +697,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$postInsertIds = $persister->executeInserts();
|
||||
|
||||
if ($postInsertIds) {
|
||||
|
@ -866,7 +867,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||
}
|
||||
|
||||
$this->_entityInsertions[$oid] = $entity;
|
||||
|
||||
|
||||
if (isset($this->_entityIdentifiers[$oid])) {
|
||||
$this->addToIdentityMap($entity);
|
||||
}
|
||||
|
|
|
@ -72,18 +72,24 @@ class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
|
|||
/**
|
||||
* @expectedException \Exception
|
||||
*/
|
||||
public function testCreateSequence()
|
||||
// This test is not correct. createSequence expects an object.
|
||||
// PHPUnit wrapping the PHP error in an exception hides this but it shows up
|
||||
// when the tests are run in the build (phing).
|
||||
/*public function testCreateSequence()
|
||||
{
|
||||
$this->_sm->createSequence('seqname', 1, 1);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
*/
|
||||
public function testCreateForeignKey()
|
||||
// This test is not correct. createForeignKey expects an object.
|
||||
// PHPUnit wrapping the PHP error in an exception hides this but it shows up
|
||||
// when the tests are run in the build (phing).
|
||||
/*public function testCreateForeignKey()
|
||||
{
|
||||
$this->_sm->createForeignKey('table', array());
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
|
|
|
@ -8,4 +8,6 @@ class SchemaManagerMock extends \Doctrine\DBAL\Schema\AbstractSchemaManager
|
|||
{
|
||||
parent::__construct($conn);
|
||||
}
|
||||
|
||||
protected function _getPortableTableColumnDefinition($tableColumn) {}
|
||||
}
|
|
@ -86,14 +86,20 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||
*/
|
||||
public function testCascadedEntitiesCallsPrePersist()
|
||||
{
|
||||
//$this->_em->getConnection()->getConfiguration()->setSqlLogger(new \Doctrine\DBAL\Logging\EchoSqlLogger);
|
||||
|
||||
$e1 = new LifecycleCallbackTestEntity;
|
||||
$e2 = new LifecycleCallbackTestEntity;
|
||||
|
||||
$c = new LifecycleCallbackCascader();
|
||||
$this->_em->persist($c);
|
||||
|
||||
$c->entities[] = $e1;
|
||||
$c->entities[] = $e2;
|
||||
|
||||
$this->_em->persist($c);
|
||||
$e1->cascader = $c;
|
||||
$e2->cascader = $c;
|
||||
|
||||
//$this->_em->persist($c);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertTrue($e1->prePersistCallbackInvoked);
|
||||
|
@ -184,7 +190,7 @@ class LifecycleCallbackCascader
|
|||
private $id;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="LifecycleCallbackTestEntity", mappedBy="product", cascade={"persist"})
|
||||
* @OneToMany(targetEntity="LifecycleCallbackTestEntity", mappedBy="cascader", cascade={"persist"})
|
||||
*/
|
||||
public $entities;
|
||||
|
||||
|
|
65
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC144Test.php
Normal file
65
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC144Test.php
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC144Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
//$this->_em->getConnection()->getConfiguration()->setSqlLogger(new \Doctrine\DBAL\Logging\EchoSqlLogger);
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC144FlowElement'),
|
||||
// $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC144Expression'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC144Operand'),
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-144
|
||||
*/
|
||||
public function testIssue()
|
||||
{
|
||||
|
||||
$operand = new DDC144Operand;
|
||||
$operand->property = 'flowValue';
|
||||
$operand->operandProperty = 'operandValue';
|
||||
$this->_em->persist($operand);
|
||||
$this->_em->flush();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="ddc144_flowelements")
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(type="string", name="discr")
|
||||
* @DiscriminatorMap({"flowelement" = "DDC144FlowElement", "operand" = "DDC144Operand"})
|
||||
*/
|
||||
class DDC144FlowElement {
|
||||
/**
|
||||
* @Id @Column(type="integer") @GeneratedValue(strategy="AUTO")
|
||||
* @var integer
|
||||
*/
|
||||
public $id;
|
||||
/** @Column(type="string") */
|
||||
public $property;
|
||||
}
|
||||
|
||||
// /** @Entity @Table(name="ddc144_expressions") */
|
||||
abstract class DDC144Expression extends DDC144FlowElement {
|
||||
abstract function method();
|
||||
}
|
||||
/** @Entity @Table(name="ddc144_operands") */
|
||||
class DDC144Operand extends DDC144Expression {
|
||||
/** @Column(type="string") */
|
||||
public $operandProperty;
|
||||
function method() {}
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue