Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Critical
-
Resolution: Invalid
-
Affects Version/s: 2.0-BETA4
-
Fix Version/s: None
-
Component/s: ORM
-
Security Level: All
-
Labels:None
Description
I have a model which looks like this:
Class A protected $collectionB = array(); // Holds many Class B instances protected $collectionC = array(); // Holds many Class C instances Class B protected $classC; // Holds one Class C instance Class C protected $attributes; // Holds many attributes which are stored in another entitty with SINGLE_TABLE discriminator
When I try to persist my object to the database, Doctrine causes this error:
Message: spl_object_hash() expects parameter 1 to be object, array given File: C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Doctrine\ORM\UnitOfWork.php Line: 2043 Trace: #0 [internal function]: PHPUnit_Util_ErrorHandler::handleError(2, 'spl_object_hash...', 'C:\Users\Sebast...', 2043, Array) #1 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Doctrine\ORM\UnitOfWork.php(2043): spl_object_hash(Array) #2 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Doctrine\ORM\Persisters\ManyToManyPersister.php(110): Doctrine\ORM\UnitOfWork->getEntityIdentifier(Array) #3 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Doctrine\ORM\Persisters\ManyToManyPersister.php(92): Doctrine\ORM\Persisters\ManyToManyPersister->_collectJoinTableColumnParameters(Object(Doctrine\ORM\PersistentCollection), Array) #4 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Doctrine\ORM\Persisters\AbstractCollectionPersister.php(124): Doctrine\ORM\Persisters\ManyToManyPersister->_getInsertRowSQLParameters(Object(Doctrine\ORM\PersistentCollection), Array) #5 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Doctrine\ORM\Persisters\AbstractCollectionPersister.php(104): Doctrine\ORM\Persisters\AbstractCollectionPersister->insertRows(Object(Doctrine\ORM\PersistentCollection)) #6 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Doctrine\ORM\UnitOfWork.php(303): Doctrine\ORM\Persisters\AbstractCollectionPersister->update(Object(Doctrine\ORM\PersistentCollection)) #7 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Doctrine\ORM\EntityManager.php(320): Doctrine\ORM\UnitOfWork->commit() #8 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_models\trunk\library\App\Model\Service\Dao\Doctrine.php(26): Doctrine\ORM\EntityManager->flush() #9 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_models\trunk\library\App\Model\Service\Abstract.php(54): App_Model_Service_Dao_Doctrine->save(Object(App_Model_Ticket)) #10 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_models\trunk\library\App\Model\Abstract.php(264): App_Model_Service_Abstract->save(Object(App_Model_Ticket)) #11 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_models\trunk\library\App\Model\Ticket.php(75): App_Model_Abstract->save() #12 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\application\controllers\TicketController.php(69): App_Model_Ticket->save() #13 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Zend\Controller\Action.php(513): TicketController->putAction() #14 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Zend\Controller\Dispatcher\Standard.php(295): Zend_Controller_Action->dispatch('putAction') #15 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_HttpTestCase), Object(Zend_Controller_Response_HttpTestCase)) #16 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\library\Zend\Test\PHPUnit\ControllerTestCase.php(199): Zend_Controller_Front->dispatch() #17 C:\Users\Sebastian Hoitz\Documents\Entwicklung\kt_api\trunk\tests\application\controllers\TicketControllerTest.php(220): Zend_Test_PHPUnit_ControllerTestCase->dispatch('/ticket/1') #18 [internal function]: TicketControllerTest->testUpdateTicketWithoutInvolvedContactsDoesNotCauseException() #19 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\Framework\TestCase.php(769): ReflectionMethod->invokeArgs(Object(TicketControllerTest), Array) #20 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\Framework\TestCase.php(659): PHPUnit_Framework_TestCase->runTest() #21 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\Framework\TestResult.php(617): PHPUnit_Framework_TestCase->runBare() #22 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\Framework\TestCase.php(607): PHPUnit_Framework_TestResult->run(Object(TicketControllerTest)) #23 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\Framework\TestSuite.php(751): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult)) #24 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\Framework\TestSuite.php(727): PHPUnit_Framework_TestSuite->runTest(Object(TicketControllerTest), Object(PHPUnit_Framework_TestResult)) #25 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\Framework\TestSuite.php(687): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult), false, Array, Array, false) #26 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\TextUI\TestRunner.php(305): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult), false, Array, Array, false) #27 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\TextUI\Command.php(188): PHPUnit_TextUI_TestRunner->doRun(Object(PHPUnit_Framework_TestSuite), Array) #28 C:\Program Files (x86)\PHP\PEAR\pear\PHPUnit\TextUI\Command.php(129): PHPUnit_TextUI_Command->run(Array, true) #29 C:\Program Files (x86)\PHP\PEAR\phpunit(53): PHPUnit_TextUI_Command::main() #30 {main}
I assume that this might happen, because of the Class B holding one Class C, and Class A also holding some Class C instances.
Those are, in some cases, the same. So when a new Class B is added, together with a new Class C, this new Class C is also added to Class A.
And somehow internally the already persisted Class C (Class B is getting persisted first) transforms the Class C instance into an array, and Doctrine can't save it anymore.
This is my guess of what happens. When I skip adding all the Class C instances to Class A, I don't get this error.
Do you get the same error if the collections are defined as ArrayCollections instead of PHP arrays ? Not sure if it is supported to use pure PHP arrays for collections.
See http://www.doctrine-project.org/projects/orm/2.0/docs/reference/association-mapping/en#collections
/** @Entity */ class A { /* ... */ public function __construct() { $this->collectionB = new \Doctrine\Common\Collections\ArrayCollection; } /** @OneToMany(targetEntity="B", mappedBy="a") */ protected $collectionB; } /** @Entity */ class B { /* ... */ /** @ManyToOne(targetEntity="A", inversedBy="collectionB") */ protected $a; }