Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
d2405ded
Commit
d2405ded
authored
May 26, 2009
by
romanb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2.0] Enhanced one-to-one self-referential association handling.
parent
3135799f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
43 additions
and
22 deletions
+43
-22
ObjectHydrator.php
lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
+5
-2
StandardEntityPersister.php
lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
+18
-11
UnitOfWork.php
lib/Doctrine/ORM/UnitOfWork.php
+18
-6
ClassTableInheritanceTest.php
...ctrine/Tests/ORM/Functional/ClassTableInheritanceTest.php
+2
-3
No files found.
lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
View file @
d2405ded
...
...
@@ -288,11 +288,14 @@ class ObjectHydrator extends AbstractHydrator
if
(
$relation
->
isOwningSide
)
{
// If there is an inverse mapping on the target class its bidirectional
if
(
isset
(
$targetClass
->
inverseMappings
[
$property
]))
{
$sourceProp
=
$targetClass
->
inverseMappings
[
$
fieldName
]
->
sourceFieldName
;
$sourceProp
=
$targetClass
->
inverseMappings
[
$
property
]
->
sourceFieldName
;
$targetClass
->
reflFields
[
$sourceProp
]
->
setValue
(
$entity2
,
$entity1
);
}
else
if
(
$classMetadata1
===
$targetClass
)
{
// Special case: self-referencing one-one on the same class
$targetClass
->
reflFields
[
$property
]
->
setValue
(
$entity2
,
$entity1
);
}
}
else
{
// For sure bidirectional, as there is no inverse side in unidirectional
// For sure bidirectional, as there is no inverse side in unidirectional
mappings
$targetClass
->
reflFields
[
$relation
->
mappedByFieldName
]
->
setValue
(
$entity2
,
$entity1
);
}
}
...
...
lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
View file @
d2405ded
...
...
@@ -23,6 +23,7 @@ namespace Doctrine\ORM\Persisters;
use
Doctrine\DBAL\Types\Type
;
use
Doctrine\ORM\EntityManager
;
use
Doctrine\ORM\UnitOfWork
;
use
Doctrine\ORM\PersistentCollection
;
use
Doctrine\ORM\Mapping\ClassMetadata
;
...
...
@@ -92,7 +93,7 @@ class StandardEntityPersister
*/
public
function
addInsert
(
$entity
)
{
$this
->
_queuedInserts
[]
=
$entity
;
$this
->
_queuedInserts
[
spl_object_hash
(
$entity
)
]
=
$entity
;
}
/**
...
...
@@ -237,16 +238,22 @@ class StandardEntityPersister
continue
;
}
//TODO: If the one-one is self-referencing, check whether the referenced entity ($newVal)
// is still scheduled for insertion. If so:
// 1) set $newVal = null, so that we insert a null value
// 2) schedule $entity for an update, so that the FK gets set through an update
// later, after the referenced entity has been inserted.
//$needsPostponedUpdate = ...
/*if ($assocMapping->sourceEntityName == $assocMapping->targetEntityName &&
isset($this->_queuedInserts[spl_object_hash($entity)])) {
echo "SELF-REFERENCING!";
}*/
// Special case: One-one self-referencing of the same class.
if
(
$newVal
!==
null
&&
$assocMapping
->
sourceEntityName
==
$assocMapping
->
targetEntityName
)
{
$oid
=
spl_object_hash
(
$newVal
);
$isScheduledForInsert
=
$uow
->
isRegisteredNew
(
$newVal
);
if
(
isset
(
$this
->
_queuedInserts
[
$oid
])
||
$isScheduledForInsert
)
{
// The associated entity $newVal is not yet persisted, so we must
// set $newVal = null, in order to insert a null value and update later.
$newVal
=
null
;
}
else
if
(
$isInsert
&&
!
$isScheduledForInsert
&&
$uow
->
getEntityState
(
$newVal
)
==
UnitOfWork
::
STATE_MANAGED
)
{
// $newVal is already fully persisted
// Clear changeset of $newVal, so that only the identifier is updated.
// Not sure this is really rock-solid here but it seems to work.
$uow
->
clearEntityChangeSet
(
$oid
);
$uow
->
propertyChanged
(
$newVal
,
$field
,
$entity
,
$entity
);
}
}
foreach
(
$assocMapping
->
sourceToTargetKeyColumns
as
$sourceColumn
=>
$targetColumn
)
{
$otherClass
=
$this
->
_em
->
getClassMetadata
(
$assocMapping
->
targetEntityName
);
...
...
lib/Doctrine/ORM/UnitOfWork.php
View file @
d2405ded
...
...
@@ -269,8 +269,6 @@ class UnitOfWork implements PropertyChangedListener
throw
$e
;
}
//TODO: commit transaction here?
// Take new snapshots from visited collections
foreach
(
$this
->
_visitedCollections
as
$coll
)
{
$coll
->
takeSnapshot
();
...
...
@@ -548,9 +546,10 @@ class UnitOfWork implements PropertyChangedListener
{
$className
=
$class
->
name
;
$persister
=
$this
->
getEntityPersister
(
$className
);
foreach
(
$this
->
_entityInsertions
as
$entity
)
{
foreach
(
$this
->
_entityInsertions
as
$
oid
=>
$
entity
)
{
if
(
get_class
(
$entity
)
==
$className
)
{
$persister
->
addInsert
(
$entity
);
unset
(
$this
->
_entityInsertions
[
$oid
]);
}
}
$postInsertIds
=
$persister
->
executeInserts
();
...
...
@@ -577,9 +576,10 @@ class UnitOfWork implements PropertyChangedListener
{
$className
=
$class
->
name
;
$persister
=
$this
->
getEntityPersister
(
$className
);
foreach
(
$this
->
_entityUpdates
as
$entity
)
{
foreach
(
$this
->
_entityUpdates
as
$
oid
=>
$
entity
)
{
if
(
get_class
(
$entity
)
==
$className
)
{
$persister
->
update
(
$entity
);
unset
(
$this
->
_entityUpdates
[
$oid
]);
}
}
}
...
...
@@ -593,9 +593,10 @@ class UnitOfWork implements PropertyChangedListener
{
$className
=
$class
->
name
;
$persister
=
$this
->
getEntityPersister
(
$className
);
foreach
(
$this
->
_entityDeletions
as
$entity
)
{
foreach
(
$this
->
_entityDeletions
as
$
oid
=>
$
entity
)
{
if
(
get_class
(
$entity
)
==
$className
)
{
$persister
->
delete
(
$entity
);
unset
(
$this
->
_entityDeletions
[
$oid
]);
}
}
}
...
...
@@ -1532,6 +1533,17 @@ class UnitOfWork implements PropertyChangedListener
$this
->
_originalEntityData
[
$oid
]
=
$data
;
$this
->
addToIdentityMap
(
$entity
);
}
/**
* INTERNAL:
* Clears the property changeset of the entity with the given OID.
*
* @param string $oid The entity's OID.
*/
public
function
clearEntityChangeSet
(
$oid
)
{
unset
(
$this
->
_entityChangeSets
[
$oid
]);
}
/* PropertyChangedListener implementation */
...
...
@@ -1552,7 +1564,7 @@ class UnitOfWork implements PropertyChangedListener
$this
->
_entityChangeSets
[
$oid
][
$propertyName
]
=
array
(
$oldValue
,
$newValue
);
if
(
isset
(
$class
->
associationMappings
[
$propertyName
]))
{
$assoc
=
$class
->
associationMappings
[
$
n
ame
];
$assoc
=
$class
->
associationMappings
[
$
propertyN
ame
];
if
(
$assoc
->
isOneToOne
()
&&
$assoc
->
isOwningSide
)
{
$this
->
_entityUpdates
[
$oid
]
=
$entity
;
}
else
if
(
$oldValue
instanceof
PersistentCollection
)
{
...
...
tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceTest.php
View file @
d2405ded
...
...
@@ -146,8 +146,7 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this
->
assertTrue
(
$result
[
0
]
instanceof
CompanyPerson
);
$this
->
assertEquals
(
'Mary Smith'
,
$result
[
0
]
->
getName
());
$this
->
assertTrue
(
$result
[
0
]
->
getSpouse
()
instanceof
CompanyEmployee
);
//var_dump($result);
$this
->
assertEquals
(
'John Smith'
,
$result
[
0
]
->
getSpouse
()
->
getName
());
$this
->
assertSame
(
$result
[
0
],
$result
[
0
]
->
getSpouse
()
->
getSpouse
());
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment