I think you're hitting an edge-case here.

Try adding a regular id to UserUnit:

    class UserUnit
    {

        /**
         * @ORM\Column(type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;

        /**
         * @ORM\ManyToOne(targetEntity="Functional\UserBundle\Entity\User", 
inversedBy="units")
         * @ORM\JoinColumn(name="user_id", referencedColumnName="id", 
nullable=false)
         */
        private $user;
        
        /**
         * 
@ORM\ManyToOne(targetEntity="Functional\BuildBundle\Entity\Unit\Unit")
         * @ORM\JoinColumn(name="unit_id", referencedColumnName="id", 
nullable=false)
         */
        private $unit;

        // ...

If things work correctly like this, you've got a workaround. I'd suggest you 
report a bug on the problems you encounter when using @version in an entity 
which uses 2 ManyToOne associations as identifier.

Pro tip: In stead of `$repo->findOneBy(array('user' => $userId, 'unit' => 
$unitId)` you can do `$repo->find(array('user' => $userId, 'unit' => $unitId)`, 
because those 2 values _are_ the identifier.

-- 
Jasper N. Brouwer
(@jaspernbrouwer)


On 12 Jan 2014, at 16:28, [email protected] wrote:

> Hi Jasper,
> 
> When i browse into the Doctrine in /vendor/doctrine, i see the doctrine 
> version is 2.4.1.
> I will explain you my case in detail to show you 2 'bugs' that i encourtered :
> 
> First here is my class :
> 
> <?php 
> 
> namespace Functional\BuildBundle\Entity\Unit;
> 
> use Doctrine\ORM\Mapping as ORM;
> 
> /**
>  * 
> @ORM\Entity(repositoryClass="Functional\BuildBundle\Entity\Unit\Repository\UserUnitRepository")
>  * @ORM\Table(name="_user_unit")
>  */
> class UserUnit
> {
>     /**
>      * @ORM\Id
>      * @ORM\ManyToOne(targetEntity="Functional\UserBundle\Entity\User", 
> inversedBy="units")
>      * @ORM\JoinColumn(name="user_id", referencedColumnName="id", 
> nullable=false)
>      */
>     private $user;
>     
>     /**
>      * @ORM\Id
>      * @ORM\ManyToOne(targetEntity="Functional\BuildBundle\Entity\Unit\Unit")
>      * @ORM\JoinColumn(name="unit_id", referencedColumnName="id", 
> nullable=false)
>      */
>     private $unit;
>     
>     /**
>      * @ORM\Column(type="integer")
>      */
>     private $value;
>     
>     /**
>      * @ORM\Version
>      * @ORM\Column(type="integer", name="version")
>      */
>     private $version;
> 
>    [...] // get and setters after this
> }
> 
> Now when i insert a first row i create it like this :
> 
> $userUnit = new UserUnit();
>                 
> $unit = $this->getUnitRepository()->find($unitId);
> $userUnit->setUnit($unit);
> $userUnit->setUser($user);
> $userUnit->setValue($quantity);
>                 
>  $this->getUserUnitRepository()->save($userUnit);
> 
> The save method call a persist and a flush on the entityManager.
> 
> At this moment i was a 'bug' because Doctrine try to find the default version 
> value to assign and there was an error (he doesn't use the id according to 
> the entities) :
> 
> ContextErrorException: Catchable Fatal Error: Object of class 
> Proxies\__CG__\Functional\BuildBundle\Entity\Unit\Unit could not be converted 
> to string in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php
>  line 695
> 
>       • in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php
>  line 695
>       • at ErrorHandler->handle('4096', 'Object of class 
> Proxies\__CG__\Functional\BuildBundle\Entity\Unit\Unit could not be converted 
> to string', 
> 'C:\Developpement\wamp3\www\Systris\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php',
>  '695', array('query' => 'SELECT version FROM _user_unit WHERE user_id = ? 
> AND unit_id = ?', 'params' => array(object(User), object(Unit)), 'types' => 
> array(), 'qcp' => null, 'logger' => object(LoggerChain), 'stmt' => 
> object(PDOStatement)))
>       • at PDOStatement->execute(array(object(User), object(Unit))) in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php
>  line 695
>       • at Connection->executeQuery('SELECT version FROM _user_unit WHERE 
> user_id = ? AND unit_id = ?', array(object(User), object(Unit))) in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php
>  line 419
>       • at Connection->fetchColumn('SELECT version FROM _user_unit WHERE 
> user_id = ? AND unit_id = ?', array(object(User), object(Unit))) in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php
>  line 336
>       • at BasicEntityPersister->fetchVersionValue(object(ClassMetadata), 
> array('user' => object(User), 'unit' => object(Unit))) in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php
>  line 311
>       • at BasicEntityPersister->assignDefaultVersionValue(object(UserUnit), 
> array('user' => object(User), 'unit' => object(Unit))) in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php
>  line 289
>       • at BasicEntityPersister->executeInserts() in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php
>  line 952
>       • at UnitOfWork->executeInserts(object(ClassMetadata)) in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php
>  line 335
>       • at UnitOfWork->commit(null) in 
> C:\Developpement\wamp3\www\Systris\vendor\doctrine\orm\lib\Doctrine\ORM\EntityManager.php
>  line 389
>       • at EntityManager->flush() in 
> C:\Developpement\wamp3\www\Systris\src\Technical\GeneralBundle\Entity\Repository\BaseEntityRepository.php
>  line 11
>       • at BaseEntityRepository->save(object(UserUnit)) in 
> C:\Developpement\wamp3\www\Systris\src\Functional\BuildBundle\Service\BuildService.php
>  line 99
>       • at BuildService->buildUnit(object(User), '1', '10', '0') in 
> C:\Developpement\wamp3\www\Systris\src\Technical\QueueBundle\Service\QueueService.php
>  line 214
> Then i wrote a quick fix for this add a __toString method to Unit object 
> returning the id as string and it works.
> 
> After this i try the update one UserUnit with this code :
> 
> $userUnit = $this->getUserUnitRepository()->findOneBy(array('user' => 
> $user->getId(), 'unit' => $unitId));
> 
> $unitEntityLockRunner = new UnitEntityLockRunner($quantity);
> $this->getUserUnitRepository()->update($userUnit, $unitEntityLockRunner);
> 
> The $userUnit object has a field version with 0 instead of having the correct 
> value from database which is 1 or 2.
> 
> If you need some extra informations please tell me and if you have some 
> explanations i will be happy to here them ;)
> 
> Thanks.
> 
> Best regards,
> David.

-- 
You received this message because you are subscribed to the Google Groups 
"doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to