[DDC-3552] Code generation throws exceptions when embeddables are used Created: 30/Jan/15  Updated: 30/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.5
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Vladislav Veselinov Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I've created a gist showing the code you can use to reproduce the issue
https://gist.github.com/v3labs/d02244c99a87444be709

I've also included the composer.json file.

When I run php app/console doctrine:generate:entities AppBundle -v, I get the following exception:

[Symfony\Component\Debug\Exception\ContextErrorException]
Notice: Trying to get property of non-object

Exception trace:
() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:3251
Symfony\Component\Debug\ErrorHandler->handleError() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:3251
Doctrine\ORM\Mapping\ClassMetadataInfo->inlineEmbeddable() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:201
Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:332
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:78
Doctrine\ORM\Mapping\ClassMetadataFactory->loadMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:225
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:115
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/doctrine-bundle/Mapping/DisconnectedMetadataFactory.php:201
Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory->getAllMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/doctrine-bundle/Mapping/DisconnectedMetadataFactory.php:164
Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory->getMetadataForNamespace() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/doctrine-bundle/Mapping/DisconnectedMetadataFactory.php:54
Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory->getBundleMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/doctrine-bundle/Command/GenerateEntitiesDoctrineCommand.php:96
Doctrine\Bundle\DoctrineBundle\Command\GenerateEntitiesDoctrineCommand->execute() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:253
Symfony\Component\Console\Command\Command->run() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:882
Symfony\Component\Console\Application->doRunCommand() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:195
Symfony\Component\Console\Application->doRun() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:96
Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:126
Symfony\Component\Console\Application->run() at /Users/vladislav/Sites/doctrine2.5_tests/app/console:27

If I add columnPreffix to the @Embed annotation the exception is different:

[Symfony\Component\Debug\Exception\ContextErrorException]
Catchable Fatal Error: Argument 1 passed to Doctrine\ORM\Mapping\ReflectionEmbeddedProperty::__construct() must be an instance of ReflectionP
roperty, null given, called in /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php on
line 952 and defined

Exception trace:
() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php:61
Symfony\Component\Debug\ErrorHandler->handleError() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php:61
Doctrine\ORM\Mapping\ReflectionEmbeddedProperty->__construct() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:952
Doctrine\ORM\Mapping\ClassMetadataInfo->wakeupReflection() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:721
Doctrine\ORM\Mapping\ClassMetadataFactory->wakeupReflection() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:343
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:78
Doctrine\ORM\Mapping\ClassMetadataFactory->loadMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:225
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:115
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/doctrine-bundle/Mapping/DisconnectedMetadataFactory.php:201
Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory->getAllMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/doctrine-bundle/Mapping/DisconnectedMetadataFactory.php:164
Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory->getMetadataForNamespace() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/doctrine-bundle/Mapping/DisconnectedMetadataFactory.php:54
Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory->getBundleMetadata() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/doctrine/doctrine-bundle/Command/GenerateEntitiesDoctrineCommand.php:96
Doctrine\Bundle\DoctrineBundle\Command\GenerateEntitiesDoctrineCommand->execute() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:253
Symfony\Component\Console\Command\Command->run() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:882
Symfony\Component\Console\Application->doRunCommand() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:195
Symfony\Component\Console\Application->doRun() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:96
Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /Users/vladislav/Sites/doctrine2.5_tests/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:126
Symfony\Component\Console\Application->run() at /Users/vladislav/Sites/doctrine2.5_tests/app/console:27

doctrine:generate:entities [--path="..."] [--no-backup] name

I don't think it's a Symfony specific issue. I tried using the built-in CLI tool and got the same results.



 Comments   
Comment by Marco Pivetta [ 30/Jan/15 ]

Yeah, this can't really work with code-gen, because embeddables require reflection to be initialized in order to operate, whereas the codegen cli-tools operate with a DisconnectedMetadataFactory, which skips reflection on purpose (it assumes that the class does not exist, therefore it does not start up reflection).

I think it's a can't fix for now.

Comment by Vladislav Veselinov [ 30/Jan/15 ]

Sorry for the formatting. I had never used jira before.

Comment by Marco Pivetta [ 30/Jan/15 ]

Vladislav Veselinov fixed the formatting, no big deal

Comment by Vladislav Veselinov [ 30/Jan/15 ]

Btw:

Changing line 947 in ClassMetadataInfo to:

if (isset($mapping['declaredField']) && $parentReflFields[$mapping['declaredField']]) {

seems to bypass the problem and the generation runs fine, but I don't know if it breaks something else. Doesn't seem like it but ... I'm not sure

Comment by Vladislav Veselinov [ 30/Jan/15 ]

Just figured out with it won't work in all cases. I'll keep digging. Thanks for the feedback!





[DDC-2988] Notice: Undefined index: joinColumns in BasicEntityPersister.php Created: 19/Feb/14  Updated: 29/Jan/15

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.3.5, 2.4.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Dennis Væversted Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File undefined-joinColumn.patch    
Issue Links:
Duplicate
duplicates DDC-2808 Notice: Undefined index: joinColumns ... Resolved

 Description   

When trying to use findBy on a ManyToMany field i receive the error:

Notice: Undefined index: joinColumns in lib/Doctrine/ORM/Persisters/BasicEntityPersister.php

It seems to be caused internally by the code expecting 'joinColumns' to be directly on the association, however it is found under 'joinTable'.
I have attached a patch that atleast fixes my case, hopefully it can be used to pin-point what the error is.



 Comments   
Comment by Dennis Væversted [ 19/Feb/14 ]

Might be related to this one: http://www.doctrine-project.org/jira/browse/DDC-2808

Comment by Litz Ouille [ 28/May/14 ]

Doctrine ORM 2.4.2 Here.

Here are my annotations
https://gist.github.com/LitzOuille/3cf2e73e169c032147ea

The thing I'm trying to do is
$questionRepository->findBy(array('contacts' => $ids)); // $ids = array(1,2,3, ...)

Comment by Marco Pivetta [ 30/May/14 ]

Calin Pristavu did you validate your mappings?

Comment by Calin Pristavu [ 30/May/14 ]

I failed, sorry.
The error came from the many-to-many condition in the entity.
Sorry for generating confusion, comment deleted !

The many-to-one works just fine !

Comment by Litz Ouille [ 03/Jun/14 ]

A little feedback? Is this a bug? Can it be fixed?
Thanks

Comment by Marco Pivetta [ 03/Jun/14 ]

Litz Ouille that particular repository call cannot work. How are we supposed to find an entity from a list of associated IDs? It would have to be the exact match...

Assuming that API would work as I envision it, it looks like a missing feature.

Dennis Væversted in order to accept a patch, we first need a failing test case demonstrating the failing scenario.

Comment by Litz Ouille [ 03/Jun/14 ]

EDIT: Ok my bad.

I am using findBy(array('id', $arrayIds)) and it is working. I thought I was using on a ManyToOne relationship, but no.

EDIT2: @ocramius In fact I would like to find all questions for which the contacts' list contains at least one id. Something like
SELECT q.*
FROM Question q, QuestionContact qc //qc = jointable
WHERE q.id = qc.question_id
AND qc.contact_id IN ($ids)

EDIT3: Actually when I try to findBy('ManyToMany', $id), it does not work either. I think I will have to use a repository for every query using a ManyToMany relationship.

EDIT4: Ok, so, as said in the original post, findBy does not work with many-to-many.
Notice: Undefined index: joinColumns (BasicEntityPersister.php line 1666)
Dump($this->class->associationMappings[$field]): https://gist.github.com/LitzOuille/51929fdc3eda5576ed31

Comment by Xander ten Boden [ 13/Jun/14 ]

I've got the same issue, also running doctrine 2.4.2:

multiple users can have multiple departments:

/**
 * @ORM\ManyToMany(targetEntity="CartelAuthDepartment", inversedBy="users")
 * @ORM\JoinTable(name="cartel_auth_user_has_cartel_auth_department",
 *		joinColumns={@ORM\JoinColumn(name="cartel_auth_user_id", referencedColumnName="id")},
 *		inverseJoinColumns={@ORM\JoinColumn(name="cartel_auth_department_id", referencedColumnName="id")}
 * )
 */
private $departments;

/**
 * @ORM\ManyToMany(targetEntity="\Cartel\AuthBundle\Entity\CartelAuth\CartelAuthUser", mappedBy="departments")
 */
private $users;

Then I want to find all the users that are within the departments that the current user has:

$aAuthUsers = $oEm->getRepository('CartelAuthBundle:CartelAuth\CartelAuthUser')->findByDepartments($aAuthDepartments);

This results in this error:

Notice: Undefined index: joinColumns in .../vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1665

Comment by Alexander [ 29/Jan/15 ]

I have same problem with doctrine 2.4.7:

Acme\ProjectBundle\Entity\Employee:
  manyToMany:
    projectbag:
      targetEntity: ProjectBag
      mappedBy: bagemployee
Acme\ProjectBundle\Entity\ProjectBag:
  manyToMany:
    bagemployee:
          targetEntity: Employee
          inversedBy: projectbag
          joinTable:
            name: ProjectBag_Employee
            joinColumns:
              ProjectBag_id:
                referencedColumnName: id
            inverseJoinColumns:
              Employee_id:
                referencedColumnName: id

$em->getRepository('AcmeProjectBundle:ProjectBag')->findBy(array('bagemployee'=>$em->getRepository('AcmeProjectBundle:Employee')->find(828)));

Notice: Undefined index: joinColumns in vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php at line 1670





[DDC-3551] [GH-1294] Avoid Connection error when calling ClassMetadataFactor::getAllMetadata() Created: 29/Jan/15  Updated: 29/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of weaverryan:

Url: https://github.com/doctrine/doctrine2/pull/1294

Message:

Hi guys!

When you pair the ORM with DBAL 2.5.0, then getting the `targetPlatform` means that a connection will be made to the database. For that reason, it's really important to not get the `targetPlatform` unless it's absolutely needed. Currently, if you call `ClassMetadataFactor::getAllMetadata()`, it will try to determine `targetPlatform` (in `initialize()`), which will make a connection. And if that connection fails (e.g. no db yet), it will blow up - even though `getAllMetadata()` doesn't need the `targetPlatform`.

This fixes that, and in an absolutely BC way, since `targetPlatform` is private (yay!). This should fix a number of issues in userland, like symfony/symfony-standard#748 and symfony/symfony-standard#774.

This is a PR to master (per the guidelines), but the real target is 2.4, since it's the latest stable. The patch won't apply cleanly, but it's simple: remove from initialize, then replace all references to the new private method.

Thanks in advance! More details are on the commit message.






[DDC-3550] [GH-1293] EntityManager::__cosntruct() as public method Created: 28/Jan/15  Updated: 28/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of mcspronko:

Url: https://github.com/doctrine/doctrine2/pull/1293

Message:






[DDC-3548] [GH-1291] Conversion to PHP 5.4's short array syntax Created: 28/Jan/15  Updated: 28/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of BenMorel:

Url: https://github.com/doctrine/doctrine2/pull/1291

Message:

Now that the minimum PHP version is 5.4, it would be good to encourage the use of the short array syntax `[]`.
Converting the existing codebase to this syntax will promote this good practice and encourage everyone to follow it.

I have converted the codebase with [a tool](https://gist.github.com/BenMorel/6994483) I wrote for personal projects:

find doctrine2 -type f -name '*.php' -exec php short-array-syntax-converter.php {} \;

The number of changes is quite large, but I'm confident that nothing is broken, and the passing tests confirm this.



 Comments   
Comment by Doctrine Bot [ 28/Jan/15 ]

A related Github Pull-Request [GH-1291] was assigned:
https://github.com/doctrine/doctrine2/pull/1291

Comment by Doctrine Bot [ 28/Jan/15 ]

A related Github Pull-Request [GH-1291] was labeled:
https://github.com/doctrine/doctrine2/pull/1291





[DDC-3452] [GH-1222] Embeddables in metadata builder Created: 17/Dec/14  Updated: 28/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of guiwoda:

Url: https://github.com/doctrine/doctrine2/pull/1222

Message:

Embeddables set the `$classMetadata->isEmbeddedClass = true` and sets `$classMetadata->isMappedSuperclass = false`, imitating the `switch` in xml / yml drivers.

Embeddeds have 2 methods, as other types have: `addEmbedded` is a one-off adder with fluent behavior, and `createEmbedded` returns an instance of `EmbeddedBuilder`. The class is very thin right now, but it's a good way to lay ground for improvements on embedded creation in the future.

This one is probably more useful than the last one, @Ocramius



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1222] was labeled:
https://github.com/doctrine/doctrine2/pull/1222

Comment by Doctrine Bot [ 26/Jan/15 ]

A related Github Pull-Request [GH-1222] was labeled:
https://github.com/doctrine/doctrine2/pull/1222

Comment by Doctrine Bot [ 28/Jan/15 ]

A related Github Pull-Request [GH-1222] was assigned:
https://github.com/doctrine/doctrine2/pull/1222

Comment by Doctrine Bot [ 28/Jan/15 ]

A related Github Pull-Request [GH-1222] was merged:
https://github.com/doctrine/doctrine2/pull/1222





[DDC-2093] Doctrine Criteria does not support sorting by relationed field Created: 20/Oct/12  Updated: 28/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Bogdan Yurov Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   
// Here I call Criteria filter
public function getWalletsActive() {
	$criteria = Criteria::create()
		->where(Criteria::expr()->eq("isRemoved", "0"))
		->orderBy(array("currency.id" => "ASC"));
	return $this->wallets->matching($criteria);
}

// Relation
/**
 * @var Currency
 *
 * @ORM\ManyToOne(targetEntity="Currency")
 * @ORM\JoinColumns({
 * @ORM\JoinColumn(name="id_currency", referencedColumnName="id")
 * })
 */
protected $currency;

// File BasicEntityPersister.php
// This cause the problem:
if ( ! isset($this->_class->fieldMappings[$fieldName])) {
    throw ORMException::unrecognizedField($fieldName);
}
// There are no relations in $this->_class->fieldMappings at all!


 Comments   
Comment by Benjamin Eberlei [ 06/Jan/13 ]

Mark as improvement.

Comment by Liverbool [ 28/Jan/15 ]

How about this?

Comment by Marco Pivetta [ 28/Jan/15 ]

Liverbool give it a try and open a PR





[DDC-2693] Attribute/association overrides should be ignored when generating entities Created: 19/Sep/13  Updated: 27/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4, 2.3.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: Joris van de Sande Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 9
Labels: command

Issue Links:
Duplicate
is duplicated by DDC-3109 [Doctrine\ORM\Mapping\MappingExceptio... Open

 Description   

The "orm:generate-entities" command fails when doctrine attribute and/or association overrides are used. So from the moment that you use an attribute/association override, it is implossible to use the generate entities command. I think that the solution to this problem is to ignore the overrides when generating entities.

The exception given in case of an attribute override is (this is executed within a Symfony2 project doctrine:generate:entities):

Generating entity "My\AppBundle\Entity\Job"

  [Doctrine\ORM\Mapping\MappingException]
  Invalid field override named 'value' for class 'My\AppBundle\Entity\Job'.

Exception trace:
 () at /path/to/project/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php:89
 Doctrine\ORM\Mapping\MappingException::invalidOverrideFieldName() at /path/to/project/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:1922
 Doctrine\ORM\Mapping\ClassMetadataInfo->setAttributeOverride() at /path/to/project/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php:564
 Doctrine\ORM\Mapping\Driver\YamlDriver->loadMetadataForClass() at /path/to/project/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php:104
 Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain->loadMetadataForClass() at /path/to/project/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:113
 Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata() at /path/to/project/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:302
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata() at /path/to/project/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:212
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor() at /path/to/project/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:112
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata() at /path/to/project/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/MetadataFactory.php:196
 Doctrine\Bundle\DoctrineBundle\Mapping\MetadataFactory->getAllMetadata() at /path/to/project/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/MetadataFactory.php:176
 Doctrine\Bundle\DoctrineBundle\Mapping\MetadataFactory->getMetadataForClass() at /path/to/project/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Mapping/MetadataFactory.php:76
 Doctrine\Bundle\DoctrineBundle\Mapping\MetadataFactory->getClassMetadata() at /path/to/project/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php:106
 Doctrine\Bundle\DoctrineBundle\Command\GenerateEntitiesDoctrineCommand->execute() at /path/to/project/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:242
 Symfony\Component\Console\Command\Command->run() at /path/to/project/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:200
 Symfony\Component\Console\Application->doRun() at /path/to/project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:83
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /path/to/project/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:106
 Symfony\Component\Console\Application->run() at /path/to/project/app/console:19


 Comments   
Comment by Rein Baarsma [ 27/Feb/14 ]

I have the same issue and it's easy to reproduce with a clean Symfony 2 setup with FOSUserBundle.
Once you add

 * @ORM\AttributeOverrides({
 *      @ORM\AttributeOverride(name="usernameCanonical",
 *          column=@ORM\Column(
 *              name     = "username_canonical",
 *              type     = "string",
 *              length   = 255,
 *              unique   = false
 *          )
 *      )
 * })

It will properly do doc:schema:update --force
But it will fail on doc:gen:entities (YourEntity)

Comment by Andy Waterman [ 13/Aug/14 ]

Not sure I agree this is minor - might not affect many users, but it's pretty blocking if you do run into it. Any ideas on a fix?

Comment by Marco Pivetta [ 13/Aug/14 ]

Andy Waterman you are supposed to manually edit generated entities anyway

Comment by Andy Waterman [ 19/Aug/14 ]

" you are supposed to manually edit generated entities anyway"

This applies to creating new entities as well as adapting old ones. Ie. Once you use an AttributeOverride anywhere in your project, you then cannot use generate:entities anywhere else.

Comment by Marco Pivetta [ 19/Aug/14 ]

Andy Waterman yes, and you are supposed to avoid the generator after the first run.

Comment by Andy Waterman [ 20/Aug/14 ]

You really cannot use the generate:entities command to generate method stubs in ANY of your entities or new entities after the first time you run it??

If this use case works as designed without AttributeOverride in the project, but not with AttributeOverrides, then it's a bug not us doing it wrong.

Comment by Cliff Odijk [ 20/Aug/14 ]

I agree with Andy Waterman that this is a bug if it works al the time and not when you use AttributeOverrides.

Now we just temporary remove the AttributeOverrides and then generate our stubs.

Comment by Cliff Odijk [ 12/Sep/14 ]

I tried to debug the issue and found that during the gatering of the class metadata you will get the DisconnectedClassMetadataFactory which gives the StaticReflectionService for the getParentClasses it returns an empty array which should be al the parent classes of an entity. Because of this the mapping information of the parent class does not exists and can't be overwritten.

Comment by Cliff Odijk [ 12/Sep/14 ]

If I implement the following code in the getParentClasses of the StaticReflectionService it work's like a charm

if ( ! class_exists($class)) {
            throw MappingException::nonExistingClass($class);
        }

        return class_parents($class);
Comment by Enrico Schultz [ 27/Jan/15 ]

This bug has been fixed by fixing DDC-1379. If you use protected variables in your base class, the schema is created correctly and the entity generator also does not generate properties twice. When using Symfony2, just set "doctrine/orm" to "2.4@dev" in "composer.json" or wait for an upcoming release.





[DDC-3545] Persist new object failed when it works with optimistic lock Created: 27/Jan/15  Updated: 27/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Max Liu Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql, orm
Environment:

PHP 5.5



 Description   

When I was trying to persist a new object, Doctrine reported a exception:

An exception occurred while executing 'SELECT version FROM wallet WHERE user_id = ?' with params [{}]:

Catchable Fatal Error: Object of class XXXBundle\Entity\User could not be converted to string in /Users/XXX/WebSite/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php line 91

From the stack trace information, I found the original exception is:

Catchable Fatal Error: Object of class XXXBundle\Entity\User could not be converted to string

The reason is that the entity Wallet has a OneToOne mapping to entity User, and user property is also marked as primary key. When the wallet object persists, Doctrine try to fetch the new version id and use user property to find object. But Doctrine doesn't handle the primary key is an object, not a basic type. So PDO can't use a object as a query parameter.

My Entity:

class Wallet
{
    /**
     * ID
     * @var User
     *
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="XXXBundle\Entity\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;

    /**
     * @var int
     *
     * @ORM\Version()
     * @ORM\Column(name="version", type="integer")
     */
    private $version;
}

I hope Doctrine team can solve this problem. My temporary solution is to override __toString method in User object. It is not elegant, doesn't it?



 Comments   
Comment by Marco Pivetta [ 27/Jan/15 ]

What exact version of the ORM is affected? Is master also behaving like this?

Comment by Max Liu [ 27/Jan/15 ]

It works well before I add version field. I didn't try with master version.





[DDC-3461] [GH-1229] Identity in onetoone association builder Created: 23/Dec/14  Updated: 26/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of guiwoda:

Url: https://github.com/doctrine/doctrine2/pull/1229

Message:



 Comments   
Comment by Doctrine Bot [ 23/Dec/14 ]

A related Github Pull-Request [GH-1229] was assigned:
https://github.com/doctrine/doctrine2/pull/1229

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1229] was labeled:
https://github.com/doctrine/doctrine2/pull/1229

Comment by Doctrine Bot [ 26/Jan/15 ]

A related Github Pull-Request [GH-1229] was unlabeled:
https://github.com/doctrine/doctrine2/pull/1229

Comment by Doctrine Bot [ 26/Jan/15 ]

A related Github Pull-Request [GH-1229] was labeled:
https://github.com/doctrine/doctrine2/pull/1229





[DDC-3319] Get the converted value in convertToDatabaseValueSQL() Created: 23/Sep/14  Updated: 25/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Benjamin Morel Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: mapping


 Description   

I have a use case where it would be useful to get the value being converted in the convertToDatabaseValueSQL() method, not just in convertToDatabaseValue().

Take the following mapping for a Geometry type:

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return $value->asBinary();
    }

    public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
    {
        return sprintf('ST_GeomFromWkb(%s, %s)', $sqlExpr, 4326);
    }

In GIS-enabled databases, ST_GeomFromWkb() takes two parameters: the WKB binary representation of the geometry, and an integer representing the SRID (coordinate system) of the geometry, in this example the hardcoded value 4326.

I would be nice to have access to the value being converted in the convertToDatabaseValueSQL() as well, to be able to get the SRID from the geometry object itself, and replace the above code with something like:

    public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform, $value)
    {
        return sprintf('ST_GeomFromWkb(%s, %s)', $sqlExpr, $value->srid());
    }

I don't think there is currently a technical way to do this (please correct me if I'm wrong).

Could we find a BC way to pass the value being converted to the convertToDatabaseValueSQL() method to add support for this use case?



 Comments   
Comment by Michael Lucas [ 25/Jan/15 ]

The use case which you described above would be a great addition to the convertToDatabaseValueSQL() or in the convertToDatabaseValue() be able to return an array of values which could be used in the convertToDatabaseValueSQL().

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return array('geometry' => $value->asBinary(), 'srid'=>$value->getSRID());
    }

    public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
    {
        return sprintf('ST_GeomFromWkb(%s, %s)', ':geometry', ':srid');
    }
Comment by Benjamin Morel [ 25/Jan/15 ]

Michael Lucas It's an interesting idea, it would work as well, although I think it might be much more complicated to implement!





[DDC-3406] Proxy returns string instead of object Created: 21/Nov/14  Updated: 25/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.x
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Martin Keckeis Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm, proxy

Issue Links:
Dependency
depends on DDC-3539 [GH-1284] #1189 DDC-3406 derived iden... Open

 Description   

I get an string in one case instead of an entity or proxy.

User -> Address -> Plant -> Hierarchy

User OneToOne Address
Address ManyToOne Plant
Plant OneToOne Hierarchy

(all are fetched as eager loading)

See PR with a test case here
https://github.com/doctrine/doctrine2/pull/1189

Reference
https://github.com/doctrine/DoctrineORMModule/issues/355



 Comments   
Comment by Doctrine Bot [ 21/Nov/14 ]

A related Github Pull-Request [GH-1189] was assigned:
https://github.com/doctrine/doctrine2/pull/1189

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1189] was labeled:
https://github.com/doctrine/doctrine2/pull/1189

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1189] was labeled:
https://github.com/doctrine/doctrine2/pull/1189

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1189] was labeled:
https://github.com/doctrine/doctrine2/pull/1189





[DDC-3539] [GH-1284] #1189 DDC-3406 derived identity in proxy must be a proxy Created: 24/Jan/15  Updated: 25/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Dependency
is required for DDC-3406 Proxy returns string instead of object Open

 Description   

This issue is created automatically through a Github pull request on behalf of Ocramius:

Url: https://github.com/doctrine/doctrine2/pull/1284

Message:

This is a horrible hack for #1189.

Not happy with it, this seems like it fixes just the symptom.



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1284] was assigned:
https://github.com/doctrine/doctrine2/pull/1284

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1284] was labeled:
https://github.com/doctrine/doctrine2/pull/1284

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1189] was labeled:
https://github.com/doctrine/doctrine2/pull/1189

Comment by Doctrine Bot [ 25/Jan/15 ]

A related Github Pull-Request [GH-1284] was unlabeled:
https://github.com/doctrine/doctrine2/pull/1284

Comment by Doctrine Bot [ 25/Jan/15 ]

A related Github Pull-Request [GH-1284] was labeled:
https://github.com/doctrine/doctrine2/pull/1284





[DDC-3534] [GH-1280] [DDC-3346] #1277 find one with eager loads is failing Created: 23/Jan/15  Updated: 25/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: Lazy Loading, ORM
Affects Version/s: Git Master
Fix Version/s: 2.5
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: collection, eager, fetch, hydrator, lazy-loading, many-to-many, onetomany, persister

Issue Links:
Dependency
is required for DDC-3346 findOneBy returns an object with part... Resolved
is required for DDC-3531 [GH-1277] [DDC-3346] Failing test for... Resolved

 Description   

This issue is created automatically through a Github pull request on behalf of Ocramius:

Url: https://github.com/doctrine/doctrine2/pull/1280

Message:

Ping @scaytrase

Note that this is a first revision and needs refactoring, so please consider helping out with that if you can.

Ping @guilhermeblanco: please check the `CachedPersisterContext` stuff: it's dirty as heck, but that's because the persister internal generated SQL caching is inconsistent as heck too.

Resolution path for 2.4.x will be to throw an exception if there is an offset or a limit.



 Comments   
Comment by Doctrine Bot [ 23/Jan/15 ]

A related Github Pull-Request [GH-1277] was assigned:
https://github.com/doctrine/doctrine2/pull/1277

Comment by Doctrine Bot [ 23/Jan/15 ]

A related Github Pull-Request [GH-1277] was closed:
https://github.com/doctrine/doctrine2/pull/1277

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1280] was labeled:
https://github.com/doctrine/doctrine2/pull/1280

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1277] was labeled:
https://github.com/doctrine/doctrine2/pull/1277

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1280] was assigned:
https://github.com/doctrine/doctrine2/pull/1280

Comment by Doctrine Bot [ 25/Jan/15 ]

A related Github Pull-Request [GH-1280] was merged:
https://github.com/doctrine/doctrine2/pull/1280





[DDC-3535] Allow binding `Parameter` value object to statements, removing the need for explicit value and type passing Created: 24/Jan/15  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: Lazy Loading, ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Task Priority: Critical
Reporter: Marco Pivetta Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: binding, criteria, parameters, persister, repository, type


 Comments   
Comment by Marco Pivetta [ 24/Jan/15 ]

We currently have a lot of locations in the code where we use list($values, $types) = $this->computeParameters(); (pseudo-code).

This leads to a lot of code duplication and complexity.

Maybe a Parameter VO may be used instead, or a ParameterCollection with a fixed $types and a mutable $values, and with minimal internal validation.





[DDC-3062] [GH-997] [FIX] Allow to use ManyToMany with all operators Created: 31/Mar/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.5
Security Level: All

Type: Bug Priority: Critical
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of bakura10:

Url: https://github.com/doctrine/doctrine2/pull/997

Message:

Hi,

ping @guillhermoblanco : I think this may be blocking for 2.5

I introduced not so long ago support for ManyToMany for Criteria. However, I realized my implementation was really incomplete, because I hard-coded the "=" operator (https://github.com/doctrine/doctrine2/pull/885/files#diff-982b7374bbe9d5f4b6b71f4869a446eaR575). This means that it fails in a lot of cases when you use something different than "eq" for Criteria.

This PR fixes that, however it's a bit hacky. The SqlExpressionVisitor was made by type hinting for a BasicEntityPersister, preventing us from using us for a collection persister. Therefore I added a new interface to keep BC.

There is also a lot of code duplication (the whole "getSelectConditionSQL" was copied from the BasicEntityPersister), but without trait or BC, I have no idea about how to solve it.

All tests pass, test were added for other operators.



 Comments   
Comment by Doctrine Bot [ 13/Jan/15 ]

A related Github Pull-Request [GH-997] was assigned:
https://github.com/doctrine/doctrine2/pull/997

Comment by Doctrine Bot [ 13/Jan/15 ]

A related Github Pull-Request [GH-997] was unassigned:
https://github.com/doctrine/doctrine2/pull/997

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-997] was labeled:
https://github.com/doctrine/doctrine2/pull/997

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-997] was labeled:
https://github.com/doctrine/doctrine2/pull/997

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-997] was unlabeled:
https://github.com/doctrine/doctrine2/pull/997





[DDC-3130] [GH-1033] [WIP] Lazy criteria for ManyToMany collection Created: 18/May/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Reference
is referenced by DDC-2535 [GH-712] Extra lazy get for inverse s... Resolved

 Description   

This issue is created automatically through a Github pull request on behalf of bakura10:

Url: https://github.com/doctrine/doctrine2/pull/1033

Message:

This continues my previous work on making Criteria most efficient.

Currently we are wrapping matching calls on repositories and matching calls on EXTRA_LAZY associations around a LazyCriteria. However, ManyToMany are still completely loaded: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/PersistentCollection.php#L874

This is still problematic from a performance point of view because count, contains... cannot be optimized. I think the solution is similar to previous one, hence creating a Lazy collection for that kind of associations.

However, this is really tricky to do because of the whole mess inside the persisters (can't wait for them to be completely refactored, it's getting really hard to maintain this mess ).



 Comments   
Comment by Doctrine Bot [ 13/Jan/15 ]

A related Github Pull-Request [GH-1033] was assigned:
https://github.com/doctrine/doctrine2/pull/1033

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1033] was labeled:
https://github.com/doctrine/doctrine2/pull/1033

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1033] was labeled:
https://github.com/doctrine/doctrine2/pull/1033

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1033] was unlabeled:
https://github.com/doctrine/doctrine2/pull/1033





[DDC-3529] [GH-1275] [WIP] Nullable embedded objects. Created: 21/Jan/15  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of lcobucci:

Url: https://github.com/doctrine/doctrine2/pull/1275

Message:

The idea was to have a simple (and clean) way to override the nullable property of embedded objects, so I've
added the ```nullable``` attribute on the ```@Embedded``` annotation and it have 3 possible values:

  • NULL: The nullable option that was defined on the attributes of the embeddable class won't be overriden;
  • TRUE: All attributes of the embeddable class will be marked as nullable and the embeddable instance only would be created when data is not NULL;
  • FALSE: All attributes of the embeddable class will be marked as non-nullable.

There's a lot of things to be improved (mostly on UnitOfWork), but it's fully working with basic tests as you can see on ValueObjectsTest::testCRUDOfNullableEmbedded() case.

I would appreciate a lot your opinions!



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1275] was labeled:
https://github.com/doctrine/doctrine2/pull/1275

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1275] was labeled:
https://github.com/doctrine/doctrine2/pull/1275





[DDC-3528] [GH-1274] PersistentCollection now extends AbstractLazyCollection. Created: 21/Jan/15  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of guilhermeblanco:

Url: https://github.com/doctrine/doctrine2/pull/1274

Message:



 Comments   
Comment by Doctrine Bot [ 22/Jan/15 ]

A related Github Pull-Request [GH-1274] was assigned:
https://github.com/doctrine/doctrine2/pull/1274

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1274] was labeled:
https://github.com/doctrine/doctrine2/pull/1274

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1274] was labeled:
https://github.com/doctrine/doctrine2/pull/1274





[DDC-3515] [GH-1263] #1223 DDC-3453 - make `EntityManager` constructor `public` Created: 18/Jan/15  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM, Tools
Affects Version/s: None
Fix Version/s: 2.5
Security Level: All

Type: Improvement Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: constructor, entitymanager, setup

Issue Links:
Reference
is referenced by DDC-3453 [GH-1223] Refactored construction of ... Resolved

 Description   

This issue is created automatically through a Github pull request on behalf of Ocramius:

Url: https://github.com/doctrine/doctrine2/pull/1263

Message:



 Comments   
Comment by Doctrine Bot [ 18/Jan/15 ]

A related Github Pull-Request [GH-1263] was assigned:
https://github.com/doctrine/doctrine2/pull/1263

Comment by Doctrine Bot [ 18/Jan/15 ]

A related Github Pull-Request [GH-1263] was assigned:
https://github.com/doctrine/doctrine2/pull/1263

Comment by Doctrine Bot [ 18/Jan/15 ]

A related Github Pull-Request [GH-1263] was unassigned:
https://github.com/doctrine/doctrine2/pull/1263

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1263] was labeled:
https://github.com/doctrine/doctrine2/pull/1263





[DDC-3510] [GH-1261] Add a new QuoteStrategy that automatically escape database reserved keyword Created: 16/Jan/15  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of xhuberty:

Url: https://github.com/doctrine/doctrine2/pull/1261

Message:

All the upload screenshots which are used to explain what we are doing are taken from a real project developed with Mouf dependency injection framework (http://mouf-php.com/) that we use to configure the entity manager.

We wanted to create a FAQ where admin can add question/answer and use drag and drop to set the position of the question in the FAQ.

For this, at some point, in an entity, we used a protected keyword "order" in a class FAQ:

```
/**

  • @ORM\Column(type="integer", nullable=false)
  • @var int
    */
    private $order;
    ```

This fails with Doctrine. The documentation clearly explains why: http://doctrine-orm.readthedocs.org/en/latest/reference/basic-mapping.html#quoting-reserved-words

Below are a list of screenshot explaining we use the `DefaultQuoteStrategy` and the failure message we get.

![doctrineconfiguration](https://cloud.githubusercontent.com/assets/8350192/5779969/4ab5c15e-9da7-11e4-8df8-f2c718c8d66a.PNG)

In the configuration,the "quoteStrategy" setter is not set. Therefore, we use `DefaultQuoteStrategy`.

![defaultquotestrategy](https://cloud.githubusercontent.com/assets/8350192/5779977/51fe0a70-9da7-11e4-9cfa-3a86e6f8aab8.PNG)

We get this error:

![error](https://cloud.githubusercontent.com/assets/8350192/5779963/422e0bc2-9da7-11e4-902c-602a2eac7f96.PNG)
We get an error while using doctrine ORM because it doesn't auto escape protected keyword. (We can protect it manually by using ` .)

We created a new QuoteStratigy that automaticcaly escape protected keyword *only*. We just bind it via the Mouf interface:

![escapingquotestrategy](https://cloud.githubusercontent.com/assets/8350192/5780067/d9997bae-9da7-11e4-8a23-c5fa2ebaffcc.PNG)

and then the magic begins: a screenshot of the page with no error.

![succes](https://cloud.githubusercontent.com/assets/8350192/5780085/f9b597f6-9da7-11e4-85b0-cd09fb572cd9.PNG)

We would like to submit this new `EscapingQuoteStrategy` as we think it will be easier for developers to work with it, and it should not have a big performance impact (only an additional lookup in a table)



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1261] was labeled:
https://github.com/doctrine/doctrine2/pull/1261

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1261] was labeled:
https://github.com/doctrine/doctrine2/pull/1261





[DDC-3507] [GH-1260] Added PersisterFactory to ORM. Created: 16/Jan/15  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of guilhermeblanco:

Url: https://github.com/doctrine/doctrine2/pull/1260

Message:



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1260] was labeled:
https://github.com/doctrine/doctrine2/pull/1260

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1260] was labeled:
https://github.com/doctrine/doctrine2/pull/1260





[DDC-3481] [GH-1241] [3.0] [POC] lazy-load on a per-property base Created: 09/Jan/15  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of Ocramius:

Url: https://github.com/doctrine/doctrine2/pull/1241

Message:

This is just a proof of concept that I hacked together real quick.

This changes how proxies are generated and lazy-loaded in a very radical way:

  • method calls do not cause lazy-loading
  • lazy-loading is triggered by access to non-transient properties (things that need to be lazy-loaded)
  • access to identifiers or non-mapped properties won't cause lazy-loading

Following BC breaks need to be fixed or discussed before going forward on this idea:

  • [ ] proxies don't implement `Doctrine\Common\Proxy\Proxy` anymore, but `ProxyManager\Proxy\GhostObjectInterface` (BC break, needs fixing, can be easily done with some effort)
  • [ ] `serialize($proxy)` now causes proxy initialization (probably needs fixing, as this is a major BC break)

Pending TODOs:

  • [ ] cloning a proxy is still not fully supported (requires dedicated logic in `__clone`)
  • [ ] this is just a PoC, so the code that writes proxies to disk is not yet in place


 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1241] was labeled:
https://github.com/doctrine/doctrine2/pull/1241

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1241] was labeled:
https://github.com/doctrine/doctrine2/pull/1241





[DDC-3458] [GH-1228] Fixed many small phpcs issues Created: 19/Dec/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of acrobat:

Url: https://github.com/doctrine/doctrine2/pull/1228

Message:

This pr fixes many small phpcs issues



 Comments   
Comment by Doctrine Bot [ 19/Dec/14 ]

A related Github Pull-Request [GH-1228] was assigned:
https://github.com/doctrine/doctrine2/pull/1228

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1228] was labeled:
https://github.com/doctrine/doctrine2/pull/1228





[DDC-3455] [GH-1225] Test for RuntimeException in AnnotationExporter::exportClassMetadata() Created: 19/Dec/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of TorbenBr:

Url: https://github.com/doctrine/doctrine2/pull/1225

Message:



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1225] was labeled:
https://github.com/doctrine/doctrine2/pull/1225

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1225] was labeled:
https://github.com/doctrine/doctrine2/pull/1225





[DDC-3446] [GH-1219] Comparison like/notlike support Created: 10/Dec/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of Fedik:

Url: https://github.com/doctrine/doctrine2/pull/1219

Message:

Support `Comparison::LIKE` and `Comparison::NOTLIKE` additionally to doctrine/collections#50

as alternative for #1150



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1219] was labeled:
https://github.com/doctrine/doctrine2/pull/1219

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1219] was labeled:
https://github.com/doctrine/doctrine2/pull/1219





[DDC-3444] [GH-1218] Failing test case for cascading refresh Created: 09/Dec/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of MartijnDwars:

Url: https://github.com/doctrine/doctrine2/pull/1218

Message:



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1218] was labeled:
https://github.com/doctrine/doctrine2/pull/1218





[DDC-3441] Unidirectional ManyToOne Not Lazy Loading Created: 09/Dec/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master, 2.4.6
Fix Version/s: None
Security Level: All

Type: Bug Priority: Critical
Reporter: Marcus Fulbright Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: lazy-loading, proxy, public-properties, reflection

Issue Links:
Dependency
depends on DDC-3442 [GH-1217] @DDC3441 failing test cases... Open

 Description   

The Unidirectional ManyToOne association described in the docs does not lazy load correctly. The appropriate SQL will get executed, and the returned Proxy does pass type hinting for the correct class. However, the lazy loaded object always has the following properties:

  • _initializer_
  • _cloner_
  • _isInitialized_
  • lazyPropertiesDefaults

Any properties from the class definition do not show up. This is problematic when trying to get reflected properties and their values. Methods are correctly reflected.

Pull request for failing test case



 Comments   
Comment by Marcus Fulbright [ 09/Dec/14 ]

Let me know if anything else is needed.

Comment by Doctrine Bot [ 11/Dec/14 ]

A related Github Pull-Request [GH-1217] was assigned:
https://github.com/doctrine/doctrine2/pull/1217

Comment by Marco Pivetta [ 11/Dec/14 ]

Looks like a current ORM limitation (private properties lazy loading).

Related:

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1217] was labeled:
https://github.com/doctrine/doctrine2/pull/1217

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1217] was labeled:
https://github.com/doctrine/doctrine2/pull/1217





[DDC-3442] [GH-1217] @DDC3441 failing test cases for the ticket Created: 09/Dec/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Dependency
is required for DDC-3441 Unidirectional ManyToOne Not Lazy Loa... Open

 Description   

This issue is created automatically through a Github pull request on behalf of MarcusFulbright:

Url: https://github.com/doctrine/doctrine2/pull/1217

Message:

Failing test cases for the ticket DDC-3441(http://www.doctrine-project.org/jira/browse/DDC-3441)



 Comments   
Comment by Marcus Fulbright [ 09/Dec/14 ]

I didn't realize a ticket would get automatically opened when I submitted a pull request. I already put relevant details for this in DDC-3441. This is a duplicate.

Comment by Doctrine Bot [ 11/Dec/14 ]

A related Github Pull-Request [GH-1217] was assigned:
https://github.com/doctrine/doctrine2/pull/1217

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1217] was labeled:
https://github.com/doctrine/doctrine2/pull/1217

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1217] was labeled:
https://github.com/doctrine/doctrine2/pull/1217





[DDC-3414] Joining on a table with inheritance produces badly formed ON clause Created: 26/Nov/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.5, 2.4.6
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Lewis Wright Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance, joins, orm, querybuilder


 Description   

When I join on a table that uses class table inheritance, Doctrine automatically joins on the parent table, but it does it before the ON clause.

So for example, writing this DQL:

SELECT uc, c FROM MyModel\Customer c LEFT JOIN MyModel\Customer uc WITH uc.customer = c

produces:

SELECT 
 # Snipped
FROM 
  customer c0_ 
  LEFT JOIN user_customer u2_ 
  INNER JOIN base_user b1_ ON u2_.id = b1_.id ON (u2_.customer_id = c0_.id)

This syntax for the ON clause looks wrong, and fails in SQLite, so I can only assume it's the result of a bug?



 Comments   
Comment by Marco Pivetta [ 26/Nov/14 ]

Please compare the DQL you wrote by hand with the one generated by the QueryBuilder

Comment by Lewis Wright [ 26/Nov/14 ]

The issue appears not to be with just the query builder, but with the DQL version too (see the updated bug report). Would it help if I made a bare-bones doctrine application demoing the problem?

Actually, what would probably be more helpful is if I added a test to the test suite for this bug. I'll see what I can do.

Comment by Marco Pivetta [ 26/Nov/14 ]

We'd need a functional test to add to the test suite, not a demo app. Sending a pull-request with a failing test case will expose the problem immediately.

Comment by Lewis Wright [ 26/Nov/14 ]

Apologies, I should have read the contribute readme first before submitting the ticket. I've created a pull request here with the failing SQLite tests:

https://github.com/doctrine/doctrine2/pull/1194

I did put this ticket number as the PR subject, but the bot seems to have created another issue here:
http://www.doctrine-project.org/jira/browse/DDC-3415

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1194] was labeled:
https://github.com/doctrine/doctrine2/pull/1194





[DDC-3415] [GH-1194] [DDC-3414] Add test for "Joining on a table with inheritance produces badly formed ON clause" Created: 26/Nov/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of LewisW:

Url: https://github.com/doctrine/doctrine2/pull/1194

Message:

Add a test for a bug report. The test is only simple with no assertions, since the SQL generated by Doctrine is invalid and generates an exception in SQLite.



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1194] was labeled:
https://github.com/doctrine/doctrine2/pull/1194





[DDC-3390] [GH-1185] add a new method that return the mapped properties Created: 12/Nov/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of fabiocarneiro:

Url: https://github.com/doctrine/doctrine2/pull/1185

Message:

There are some implementations that use the doctrine metadata to get the properties of a entity (DoctrineObject), and it currently uses the getFieldNames and getAssociationNames methods to retrieve and merge it.

Since the embeddables feature was added, that method will return more than one metadata for each embeddable property, and then the hydrator can never find the appropriate setter for that property.

This method allows some implementation to retrieve all mapped fields from an entity, something that can't be done using get_class_vars for example.

Of course this implementation could be done in the hydrator, but i don't think it is its responsibility to filter and merge data received from the ClassMetadata. Since you have methods to retrieve the metadata formatted as the database structure, you should also have methods to retrieve the information to the other side, in object structure.



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1185] was labeled:
https://github.com/doctrine/doctrine2/pull/1185





[DDC-3383] [GH-1179] Fix embeddables class metadata (work-in-progress) Created: 10/Nov/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of fabiocarneiro:

Url: https://github.com/doctrine/doctrine2/pull/1179

Message:

ClassMetadataInfo is returning more than one result in getFieldNames() for the embeddables properties. This method is used by DoctrineModule\Stdlib\Hydrator\DoctrineObject in the extraction process.

Since its returning a number of results equal the number of properties of the embedded object, it will never find the correct setter for the extraction and that causes that property to be removed from the extracted array.

I was able to solve the issue by hacking into the getFieldNames() for testing and merging the duplicated entries, and then the object was successfully extracted.

By digging into the code, i found out that there is a mapEmbedded(), but instead of using that for embeddeds, its using the default mapField, which may be the root cause of the problem.

  • [x] Hack into the getFieldNames() method to see if the expected solution would work
  • [x] Remove multiple class declaration in the same file from the files i'll work with
  • [x] Create a failing testcase
  • [ ] Create a solution


 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1179] was labeled:
https://github.com/doctrine/doctrine2/pull/1179

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1179] was labeled:
https://github.com/doctrine/doctrine2/pull/1179





[DDC-1952] Add support for array parameters on the SQLFilter Created: 27/Jul/12  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Menno Holtkamp Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: None


 Description   

The SQLFilter currently only accepts string parameters which would result in SQL like:

"tableAlias.column = '$filterParameter'"

To filter an Entity that has a lifecycle, this can be usefull to filter Entities that are in a specific state, for example:

"tableAlias.state = 1"

To be able to apply the filter on an Entity that can be in multiple states, it is usefull to be able to assign an array of states using setParameter:

$allowedStates = array(1,2,3,4);
$filter->setParameter('allowedStatesParam', $allowedStates);
sprintf("tableAlias.state IN (%s)", implode(',', $this->getParameter('allowedStatesParam')));

to eventually result in:

"tableAlias.state IN (1,2,3,4)"

However, this is currently not supported, it seems to go wrong on the PDO::quote() of the parameter. The SQL works ok when setting it statically in the filter, not taking the parameter into account.

It would be nice to have support for arrays on the setParameter()



 Comments   
Comment by Petr 'PePa' Pavel [ 24/Oct/14 ]

I've just created a pull request that implements just that. The only difference is that you don't call implode on the parameter when using it.
https://github.com/doctrine/doctrine2/pull/1168

The usage would be:

$allowedStates = array(1,2,3,4);
$filter->setParameter('allowedStatesParam', $allowedStates);

$quotedList = $this->getParameter('allowedStatesParam');
"tableAlias.state IN ($quotedList)"
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1168] was labeled:
https://github.com/doctrine/doctrine2/pull/1168





[DDC-3362] [GH-1168] [DDC-1952] Support for array parameters on the SQLFilter Created: 24/Oct/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of xpavp03:

Url: https://github.com/doctrine/doctrine2/pull/1168

Message:

Allows passing an array to SQLFilter parameter and have each item pass through quote() before turning the whole array into a comma-separated list.

For purpose see here:
http://www.doctrine-project.org/jira/browse/DDC-1952

Exception is made for types that Doctrine already recognizes as an array and stores as their derivate (array, simple_array, json_array).



 Comments   
Comment by Doctrine Bot [ 24/Oct/14 ]

A related Github Pull-Request [GH-1168] was assigned:
https://github.com/doctrine/doctrine2/pull/1168

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1168] was labeled:
https://github.com/doctrine/doctrine2/pull/1168





[DDC-3332] [GH-1152] Adds error message when the key is composite Created: 02/Oct/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of fran6co:

Url: https://github.com/doctrine/doctrine2/pull/1152

Message:

An example is:

```
SELECT u FROM User u INNER JOIN Address a ON a.user = u
```

When User has a composite key.



 Comments   
Comment by Doctrine Bot [ 02/Oct/14 ]

A related Github Pull-Request [GH-1152] was assigned:
https://github.com/doctrine/doctrine2/pull/1152

Comment by Doctrine Bot [ 17/Jan/15 ]

A related Github Pull-Request [GH-1152] was assigned:
https://github.com/doctrine/doctrine2/pull/1152

Comment by Doctrine Bot [ 17/Jan/15 ]

A related Github Pull-Request [GH-1152] was unassigned:
https://github.com/doctrine/doctrine2/pull/1152

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1152] was labeled:
https://github.com/doctrine/doctrine2/pull/1152

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1152] was labeled:
https://github.com/doctrine/doctrine2/pull/1152





[DDC-3328] [GH-1150] Improve Comparison::CONTAINS: allow to use custom position for % and _ wildcard characters Created: 28/Sep/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of Fedik:

Url: https://github.com/doctrine/doctrine2/pull/1150

Message:

This pull prevent forced wrapping of the value in to `%`
and allow to use the custom position for `%` and `_` wildcard characters in case `Comparison::CONTAINS`

Allow to build the `contains` expressions like:
```php
Criteria::expr()->contains('myField', 'some string%');
Criteria::expr()->contains('myField', '%some string');
Criteria::expr()->contains('myField', '10%');
Criteria::expr()->contains('myField', 's_m_ string');
```



 Comments   
Comment by Doctrine Bot [ 19/Oct/14 ]

A related Github Pull-Request [GH-1150] was assigned:
https://github.com/doctrine/doctrine2/pull/1150

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1150] was labeled:
https://github.com/doctrine/doctrine2/pull/1150





[DDC-3313] [GH-1139] Single entity flush Created: 18/Sep/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of goetas:

Url: https://github.com/doctrine/doctrine2/pull/1139

Message:

The current `flush` behavior seems to be inconsistent or not well documented.



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1139] was labeled:
https://github.com/doctrine/doctrine2/pull/1139

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1139] was labeled:
https://github.com/doctrine/doctrine2/pull/1139





[DDC-2879] Persisting collections with Composite Primary Keys composed of 2 Foreign Keys and one metadata field Created: 31/Dec/13  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Dylan Johnson Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: composite, identity, mapping, orm, postgresql
Environment:

Ubuntu 13.04 and PostgresSQL 9.1.0 on Vagrant Virtual Machine running an application with Symfony2 backend and JavaScript client



 Description   

SYNOPSIS

Bug prevents persisting a collection of entities in a join table with a Composite Primary
Key made up of 2 Foreign Keys and one metadata field. From these mapping instructions:
http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-3-join-table-with-metadata

ISSUE DETAILS

SUCCESS: When FOREIGN KEY 1 is the same across items in a collection to be persisted, and FOREIGN KEY 2 is greater than FOREIGN KEY 2 in any existing PRIMARY KEY, the entity and collection are persisted correctly

    • Example: GPA "add val below" exists and has assessment value
      {"grade_point_average_id":1,"assessment_id":1,"value":4}

      We will try to add a new assessment value where assessment_id > that of any existing assessment value for GPA "add val below"

    • Request Payload:
      {"name":"Add Val Below","courses":[],"assessmentValues":[{"assessment":1,"value":4},{"assessment":3,"value":2}]}
    • Debug Log:
      [2014-01-07 11:48:01] app.INFO: START GRADE_POINT_AVERAGE_REPOSITORY #SAVE [GPA #GET_NAME =ADD VAL BELOW] [] []
      [2014-01-07 11:48:01] app.INFO:   BEGIN OUTPUT FOR GRADE POINT AVERAGE Add Val Below - ASSESSMENT VALUE 1 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_GRADE_POINT_AVERAGE #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         GRADE_POINT_AVERAGE #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_ASSESSMENT #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_VALUE: 4 [] []
      [2014-01-07 11:48:01] app.INFO:         MANAGED? 1 [] []
      [2014-01-07 11:48:01] app.INFO:   END OUTPUT FOR GRADE POINT AVERAGE Add Val Below - ASSESSMENT VALUE 2 [] []
      [2014-01-07 11:48:01] app.INFO:   BEGIN OUTPUT FOR GRADE POINT AVERAGE Add Val Below - ASSESSMENT VALUE 2 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_GRADE_POINT_AVERAGE #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         GRADE_POINT_AVERAGE #GET_ID: 1 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_ASSESSMENT #GET_ID: 3 [] []
      [2014-01-07 11:48:01] app.INFO:         ASSESSMENT_VALUE #GET_VALUE: 2 [] []
      [2014-01-07 11:48:01] app.INFO:         MANAGED?  [] []
      [2014-01-07 11:48:01] app.INFO:   END OUTPUT FOR GRADE POINT AVERAGE Add Val Below - ASSESSMENT VALUE 3 [] []
      [2014-01-07 11:48:01] app.INFO: END GRADE_POINT_AVERAGE_REPOSITORY #SAVE [GPA #GET_NAME =ADD VAL BELOW] [] []
      [2014-01-07 11:48:01] doctrine.DEBUG: "START TRANSACTION" [] []
      [2014-01-07 11:48:01] doctrine.DEBUG: INSERT INTO gpa_assessment_value (point_value, grade_point_average_id, assessment_id) VALUES (?, ?, ?) {"1":2,"2":"1","3":"3"} []
      [2014-01-07 11:48:01] doctrine.DEBUG: UPDATE gpa_assessment_value SET point_value = ? WHERE grade_point_average_id = ? AND assessment_id = ? [4,1,1] []
      [2014-01-07 11:48:01] doctrine.DEBUG: "COMMIT" [] []

FAILURE: When FOREIGN KEY 1 is the same across items in a collection, and FOREIGN KEY 2 is less than any existing FOREIGN KEY 2, the unit of work tries to INSERT existing entity and does not operate on new entity. The EntityManager thinks it contains() the new entity, but not the old one

    • Example: GPA "add val above" exists and has assessment value
      {"assessment":3,"value":2}

      We will try to add a new assessment value where assessment_id < that of any existing assessment value for GPA "add val above"

    • Request Payload:
      {"name":"Add Val Above","courses":[],"assessmentValues":[{"assessment":1,"value":4},{"assessment":3,"value":2}]}
    • Debug log:
      [2014-01-07 11:47:09] app.INFO: START GRADE_POINT_AVERAGE_REPOSITORY #SAVE [GPA #GET_NAME =ADD VAL ABOVE] [] []
      [2014-01-07 11:47:09] app.INFO:   BEGIN OUTPUT FOR GRADE POINT AVERAGE Add Val Above - ASSESSMENT VALUE 1 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_GRADE_POINT_AVERAGE #GET_ID: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         GRADE_POINT_AVERAGE #GET_ID: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_ASSESSMENT #GET_ID: 1 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_VALUE: 4 [] []
      [2014-01-07 11:47:09] app.INFO:         MANAGED? 1 [] []
      [2014-01-07 11:47:09] app.INFO:   END OUTPUT FOR GRADE POINT AVERAGE Add Val Above - ASSESSMENT VALUE 2 [] []
      [2014-01-07 11:47:09] app.INFO:   BEGIN OUTPUT FOR GRADE POINT AVERAGE Add Val Above - ASSESSMENT VALUE 2 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_GRADE_POINT_AVERAGE #GET_ID: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         GRADE_POINT_AVERAGE #GET_ID: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_ASSESSMENT #GET_ID: 3 [] []
      [2014-01-07 11:47:09] app.INFO:         ASSESSMENT_VALUE #GET_VALUE: 2 [] []
      [2014-01-07 11:47:09] app.INFO:         MANAGED?  [] []
      [2014-01-07 11:47:09] app.INFO:   END OUTPUT FOR GRADE POINT AVERAGE Add Val Above - ASSESSMENT VALUE 3 [] []
      [2014-01-07 11:47:09] app.INFO: END GRADE_POINT_AVERAGE_REPOSITORY #SAVE [GPA #GET_NAME =ADD VAL ABOVE] [] []
      [2014-01-07 11:47:09] doctrine.DEBUG: "START TRANSACTION" [] []
      [2014-01-07 11:47:09] doctrine.DEBUG: INSERT INTO gpa_assessment_value (point_value, grade_point_average_id, assessment_id) VALUES (?, ?, ?) {"1":2,"2":"2","3":"3"} []
      [2014-01-07 11:47:09] doctrine.DEBUG: "ROLLBACK" [] []
      [2014-01-07 11:47:09] event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\Security\Http\Firewall\ExceptionListener::onKernelException". [] []
      [2014-01-07 11:47:09] event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelException". [] []
      [2014-01-07 11:47:09] event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\HttpKernel\EventListener\ExceptionListener::onKernelException". [] []
      [2014-01-07 11:47:09] request.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\DBALException: "An exception occurred while executing 'INSERT INTO gpa_assessment_value (point_value, grade_point_average_id, assessment_id) VALUES (?, ?, ?)' with params [2, "2", "3"]:
      
      SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint "gpa_assessment_value_pkey"
      DETAIL:  Key (grade_point_average_id, assessment_id)=(2, 3) already exists." at /vagrant/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php line 47 {"exception":"[object] (Doctrine\\DBAL\\DBALException: An exception occurred while executing 'INSERT INTO gpa_assessment_value (point_value, grade_point_average_id, assessment_id) VALUES (?, ?, ?)' with params [2, \"2\", \"3\"]:\n\nSQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint \"gpa_assessment_value_pkey\"\nDETAIL:  Key (grade_point_average_id, assessment_id)=(2, 3) already exists. at /vagrant/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:47, PDOException: SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint \"gpa_assessment_value_pkey\"\nDETAIL:  Key (grade_point_average_id, assessment_id)=(2, 3) already exists. at /vagrant/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php:138)"} []
         

CODE

migration.sql
CREATE TABLE assessment
(
    id       bigserial NOT NULL,
    scale_id bigint    NOT NULL,
    title    varchar   NOT NULL,
    passing  boolean   NOT NULL,
    rank     int,

    PRIMARY KEY (id)
);

CREATE TABLE assessment_scale
(
    id   bigserial NOT NULL,
    name varchar   NOT NULL,

    PRIMARY KEY (id)
);

-- ...

CREATE TABLE grade_point_average
(
    id                         bigserial       NOT NULL,
    name                       varchar         NOT NULL,
    additional_credit_allowance numeric(4, 2),

    PRIMARY KEY (id)
);

-- ...

CREATE TABLE gpa_assessment_value
(
    grade_point_average_id bigint        NOT NULL,
    assessment_id          bigint        NOT NULL,
    point_value            numeric(4, 2) NOT NULL,

    PRIMARY KEY (assessment_id, grade_point_average_id),
    FOREIGN KEY (assessment_id) REFERENCES assessment,
    FOREIGN KEY (grade_point_average_id) REFERENCES grade_point_average
);
GradePointAverage.php
<?php
namespace LGSConnect\Model;

use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;
//...
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use LGSConnect\Util\ConstructorArgs;
use LGSConnect\Model\GradePointAverage\AssessmentValue;
// ...

/**
 * @Entity("LGSConnect\Repository\GradePointAverageRepository")
 */
class GradePointAverage
{
    // GradePointAverage Model (owning side): a tool for evaluating a student's performance 
    // by dividing the total points earned by total credits attempted.

    use ConstructorArgs;

    /**
     * @Id
     * @GeneratedValue
     * @Column(type="bigint")
     *
     * @var int
     */
    private $id;

    // ...

    /**
     * @OneToMany(targetEntity="LGSConnect\Model\GradePointAverage\AssessmentValue", mappedBy="gradePointAverage", cascade="persist")
     *
     * @var Collection
     */
    private $assessmentValues;
    
    // ...

    /**
     * @param array $args
     */
    public function __construct(array $args = [])
    {
        $this->assessmentValues = new ArrayCollection;
        // ...
        $this->handleArgs($args);
    }
    
    // ...
    
    /**
     * @return Collection
     */
    public function getAssessmentValues()
    {
        return $this->assessmentValues;
    }

    /**
     * @param ArrayCollection $assessmentValues
     */
    public function setAssessmentValues(ArrayCollection $assessmentValues)
    {
        $this->assessmentValues = $assessmentValues;
    }

    /**
     * @param AssessmentValue $assessmentValue
     */
    public function addAssessmentValue(AssessmentValue $assessmentValue)
    {
        $this->assessmentValues->add($assessmentValue);
    }

    /**
     * @param AssessmentValue $assessmentValue
     */
    public function removeAssessmentValue(AssessmentValue $assessmentValue)
    {
        $this->assessmentValues->removeElement($assessmentValue);
    }
    
    // ...
}
AssessmentValue.php
<?php
namespace LGSConnect\Model\GradePointAverage;

use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\JoinColumn;
use LGSConnect\Model\GradePointAverage;
use LGSConnect\Model\Assessment;
use LGSConnect\Util\ConstructorArgs;

/**
 * @Entity("LGSConnect\Repository\GradePointAverage\AssessmentValueRepository")
 * @Table("gpa_assessment_value")
 */
class AssessmentValue
{
    // AssessmentValue Model (inverse side): a number of points assigned 
    // to an Assessment by a Grade Point Average

    use ConstructorArgs;

    /**
     * @Id
     * @ManyToOne(targetEntity="LGSConnect\Model\GradePointAverage")
     */
    private $gradePointAverage;

    /**
     * @Id
     * @ManyToOne(targetEntity="LGSConnect\Model\Assessment")
     */
    private $assessment;

    /**
     * @Column("point_value")
     *
     * @var float
     */
    private $value;

    /**
     * @param array $args
     */
    public function __construct(array $args = [])
    {
        $this->handleArgs($args);
    }

    /**
     * @return GradePointAverage
     */
    public function getGradePointAverage()
    {
        return $this->gradePointAverage;
    }

    /**
     * @param GradePointAverage $gradePointAverage
     */
    public function setGradePointAverage(GradePointAverage $gradePointAverage)
    {
        $this->gradePointAverage = $gradePointAverage;
    }

    /**
     * @return Assessment
     */
    public function getAssessment()
    {
        return $this->assessment;
    }

    /**
     * @param Assessment $assessment
     */
    public function setAssessment(Assessment $assessment)
    {
        $this->assessment = $assessment;
    }

    /**
     * @return float
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * @param float $value
     */
    public function setValue($value)
    {
        $this->value = $value;
    }

    /**
     * @return AssessmentScale
     */
    public function getAssessmentScale()
    {
        return $this->assessment->getScale();
    }
}
Assessment.php
<?php
namespace LGSConnect\Model;

use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\ManyToOne;
use LGSConnect\Model\Assessment\Scale;
use LGSConnect\Util\ConstructorArgs;

/**
 * @Entity("LGSConnect\Repository\AssessmentRepository")
 */
class Assessment
{
    // Assessment (related, but unmapped): A "grade" assigned to a student 
    // for attending a course section

    use ConstructorArgs;

    /**
     * @Id
     * @GeneratedValue
     * @Column(type="bigint")
     *
     * @var int
     */
    private $id;
    
    // ...

    /**
     * @param array $args
     */
    public function __construct(array $args = [])
    {
        $this->handleArgs($args);
    }

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
    
    // ...
}
GradePointAverageRepository.php
<?php
namespace LGSConnect\Repository;

use Doctrine\ORM\EntityRepository;
// ...
use LGSConnect\Model\GradePointAverage;

class GradePointAverageRepository extends BaseRepository implements GradePointAverageRepositoryInterface
{
    // ...

    /**
     * @param GradePointAverage $gradePointAverage
     */
    public function save(GradePointAverage $gradePointAverage)
    {
        $this->getEntityManager()->persist($gradePointAverage);
        $this->getEntityManager()->flush();
    }
}
AssessmentValueRepository.php
<?php
namespace LGSConnect\Repository\GradePointAverage;

use Doctrine\ORM\EntityRepository;
use LGSConnect\Model\GradePointAverage\AssessmentValue;

class AssessmentValueRepository extends EntityRepository
{
    /**
     * @param AssessmentValue $assessmentValue
     */
    public function save(AssessmentValue $assessmentValue)
    {
        $this->getEntityManager()->persist($assessmentValue);
        $this->getEntityManager()->flush();
    }
}
GradePointAverageManager.php
<?php
namespace LGSConnect\Manager;

use InvalidArgumentException;
use Symfony\Component\Validator\ValidatorInterface;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\SecurityExtraBundle\Annotation\PreAuthorize;
use Knp\Component\Pager\Pagination\PaginationInterface;
use LGSConnect\Repository\GradePointAverageRepository;
use LGSConnect\PaginationFactory\GradePointAveragePaginationFactoryInterface;
use LGSConnect\Model\GradePointAverage;

/**
 * @Service("grade_point_average_manager")
 */
class GradePointAverageManager
{
    /**
     * @var GradePointAverageRepository
     */
    private $gradePointAverageRepository;

    /**
     * @var GradePointAveragePaginationFactoryInterface
     */
    private $gradePointAveragePaginationFactory;

    /**
     * @var ValidatorInterface
     */
    private $validator;

    /**
     * @InjectParams
     *
     * @param GradePointAverageRepository $gradePointAverageRepository
     * @param GradePointAveragePaginationFactoryInterface $gradePointAveragePaginationFactory
     * @param ValidatorInterface $validator
     */
    public function __construct(
        GradePointAverageRepository $gradePointAverageRepository,
        GradePointAveragePaginationFactoryInterface $gradePointAveragePaginationFactory,
        ValidatorInterface $validator
    )
    {
        $this->gradePointAverageRepository = $gradePointAverageRepository;
        $this->gradePointAveragePaginationFactory = $gradePointAveragePaginationFactory;
        $this->validator = $validator;
    }

    /**
     * @PreAuthorize("isAllowedToManageTheGradePointAverage(#gradePointAverage)")
     * @param GradePointAverage $gradePointAverage
     * @throws InvalidArgumentException
     */
    public function save(GradePointAverage $gradePointAverage)
    {
        $violationList = $this->validator->validate($gradePointAverage);
        if ($violationList->count()) {
            throw new InvalidArgumentException;
        }

        $this->gradePointAverageRepository->save($gradePointAverage);
    }
}
GradePointAverageController.php
<?php
namespace LGSConnect\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Doctrine\Common\Collections\ArrayCollection;
use FOS\RestBundle\View\View;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\SecurityExtraBundle\Annotation\PreAuthorize;
use Knp\Component\Pager\Pagination\PaginationInterface;
use LGSConnect\Manager\GradePointAverageManager;
use LGSConnect\Model\GradePointAverage;
use LGSConnect\Model\GradePointAverage\AssessmentValue;

/**
 * @Service("grade_point_average_controller", parent="lgs.controller.abstract")
 * @Route("/gpa", service="grade_point_average_controller")
 */
class GradePointAverageController extends BaseController
{
    /**
     * @var GradePointAverageManager
     */
    private $gradePointAverageManager;

    private $logger;

    /**
     * @InjectParams
     *
     * @param GradePointAverageManager $gradePointAverageManager
     * @param LoggerInterface $logger
     */
    public function __construct(GradePointAverageManager $gradePointAverageManager, LoggerInterface $logger)
    {
        $this->gradePointAverageManager = $gradePointAverageManager;
        $this->logger = $logger;
    }
    
    // ...

    /**
     * @Route("/{id}", name="gpa.edit", requirements={"id" = "\d+"})
     * @Method("PUT")
     *
     * @param Request $request
     * @param GradePointAverage $gpa
     * @return View
     */
    public function editAction(Request $request, GradePointAverage $gpa)
    {
        $form = $this->formFactory->createNamed(null, 'gpa', $gpa, [
            'method' => 'PUT',
        ]);
        $form->handleRequest($request);

        foreach ($gpa->getAssessmentValues() as $av) {
            $this->logger->info('GPA ID PREVALIDATE IN CONTROLLER:'.$gpa->getId());
            $this->logger->info('PREVALIDATE IN CONTROLLER ASSESSMENT VAL ASSESSMENT ID:'.$av->getAssessment()->getId());
            $this->logger->info('PREVALIDATE IN CONTROLLER ASSESSMENT VAL POINTS:'.$av->getValue());
        }

        /*
        // try reversing the order of the collection to see if that helps
        $assessmentVals = $gpa->getAssessmentValues()->toArray();
        $reversed = array_reverse($assessmentVals);
        $reversedColl = new ArrayCollection($reversed);
        $gpa->setAssessmentValues($reversedColl);
        */

        if ($form->isValid()) {
            foreach ($gpa->getAssessmentValues() as $av) {
                $this->logger->info('GPA ID PRESAVE IN CONTROLLER:'.$gpa->getId());
                $this->logger->info('PRESAVE IN CONTROLLER ASSESSMENT VAL ASSESSMENT ID:'.$av->getAssessment()->getId());
                $this->logger->info('PRESAVE IN CONTROLLER ASSESSMENT VAL POINTS:'.$av->getValue());
            }
            $this->gradePointAverageManager->save($gpa);

            return new View($gpa, 204);
        }

        return new View($form);
    }

    // ...
}
GradePointAverageType.php
<?php
namespace LGSConnect\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use JMS\DiExtraBundle\Annotation\FormType;

/**
 * @FormType
 */
class GradePointAverageType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('courses', 'entity', [
                'class' => 'Model:Course',
                'multiple' => true
            ])
            ->add('assessmentValues', 'collection', [
                'type' => 'gpa_assessment_value',
                'allow_add' => true,
                'by_reference' => false,
            ])
        ;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'gpa';
    }
}
AssessmentValueType.php
<?php
namespace LGSConnect\Form\Type\GradePointAverage;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use JMS\DiExtraBundle\Annotation\FormType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

/**
 * @FormType("gpa_assessment_value")
 */
class AssessmentValueType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('assessment', 'entity', [
                'class' => 'Model:Assessment',
            ])
            ->add('value', 'number', [
                'precision' => 2,
            ])
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'LGSConnect\Model\GradePointAverage\AssessmentValue',
        ]);
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'gpa_assessment_value';
    }
}


 Comments   
Comment by Valentin Nazarov [ 23/Jan/15 ]

Any update on this issue? We've got same problem in our project (PostgreSQL 9.4, Doctrine 2.4.7)

Comment by Marco Pivetta [ 24/Jan/15 ]

Removed the "feedback required" flag.

Valentin Nazarov if there is no ticket update, well... then there is no actual update.

Somewhat related to https://github.com/doctrine/doctrine2/pull/1113

I suggest getting your hands dirty and fixing it yourself if it affects you.

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1113] was labeled:
https://github.com/doctrine/doctrine2/pull/1113

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1113] was labeled:
https://github.com/doctrine/doctrine2/pull/1113





[DDC-3259] Second level & UnitOfWork inconsistencies Created: 19/Aug/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Asmir Mustafic Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: second-level-cache


 Description   

Hi!

I have a lot of entities with entity associations as keys and I'm trying to use second level cache.

Looking at the method: UnitOfWork::createEntity($className, array $data, &$hints = array())

  • $className: contains the class name
  • $data: contains the raw data (the row coming from the database)

Enabling the second level cache, DefaultQueryCache::get calls the createEntity method passing a $data that contains object entities and some raw data (https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Cache/DefaultQueryCache.php#L155).

I think that DefaultQueryCache should not introduce a variant of $data and should create a compatible version of $data.



 Comments   
Comment by Marco Pivetta [ 19/Aug/14 ]

Asmir Mustafic do you have any example of where this may be happening?

Comment by Asmir Mustafic [ 19/Aug/14 ]

https://github.com/doctrine/doctrine2/pull/1114

This is the same branch of https://github.com/doctrine/doctrine2/pull/1113, plus this commit (https://github.com/goetas/doctrine2/commit/bfbbb9123fd28f7fa053b76895eaa77e00095aa6) that simply involves the second level cache too.
Travis should fail soon.

Comment by Doctrine Bot [ 19/Aug/14 ]

A related Github Pull-Request [GH-1114] was closed:
https://github.com/doctrine/doctrine2/pull/1114

Comment by Asmir Mustafic [ 19/Aug/14 ]

Here the failure https://travis-ci.org/doctrine/doctrine2/jobs/32972996#L402

Comment by Doctrine Bot [ 22/Oct/14 ]

A related Github Pull-Request [GH-1113] was assigned:
https://github.com/doctrine/doctrine2/pull/1113

Comment by Doctrine Bot [ 18/Jan/15 ]

A related Github Pull-Request [GH-1113] was closed:
https://github.com/doctrine/doctrine2/pull/1113

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1113] was labeled:
https://github.com/doctrine/doctrine2/pull/1113

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1113] was labeled:
https://github.com/doctrine/doctrine2/pull/1113





[DDC-3258] [GH-1113] Added support for composite primary key on findBy methods and Criteria Created: 18/Aug/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by DDC-3260 [GH-1114] Composite pk break test Resolved
is duplicated by DDC-3316 [GH-1141] Always allow proxies on ToO... Resolved

 Description   

This issue is created automatically through a Github pull request on behalf of goetas:

Url: https://github.com/doctrine/doctrine2/pull/1113

Message:

Hi!
I tried to implement the matching of entities that uses composite primary keys...

Any suggestion?



 Comments   
Comment by Doctrine Bot [ 22/Oct/14 ]

A related Github Pull-Request [GH-1113] was assigned:
https://github.com/doctrine/doctrine2/pull/1113

Comment by Doctrine Bot [ 18/Jan/15 ]

A related Github Pull-Request [GH-1113] was closed:
https://github.com/doctrine/doctrine2/pull/1113

Comment by Doctrine Bot [ 18/Jan/15 ]

A related Github Pull-Request [GH-1113] was reopened:
https://github.com/doctrine/doctrine2/pull/1113

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1113] was labeled:
https://github.com/doctrine/doctrine2/pull/1113

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1113] was labeled:
https://github.com/doctrine/doctrine2/pull/1113





[DDC-3200] [GH-1077] Support filter parameters in Configuration Created: 01/Jul/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of jmikola:

Url: https://github.com/doctrine/doctrine2/pull/1077

Message:

Based on work done in doctrine/mongodb-odm#908

My understanding is that this makes it easier to setup filters at boot time, instead of having to fetch them from the collection later on.

For added context, the related PR from MongoDB ODM's Symfony bundle is doctrine/DoctrineMongoDBBundle#255



 Comments   
Comment by Doctrine Bot [ 11/Nov/14 ]

A related Github Pull-Request [GH-1077] was assigned:
https://github.com/doctrine/doctrine2/pull/1077

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-1077] was labeled:
https://github.com/doctrine/doctrine2/pull/1077





[DDC-3044] [GH-986] Add last modified time for metadata Created: 22/Mar/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of c960657:

Url: https://github.com/doctrine/doctrine2/pull/986

Message:

This patch improves performance during development and does not affect production performance.

Currently, enabling the metadata cache during development gives a remarkable performance boost, but it requires that you manually flush the metadata cache when the metadata has been changed. When running console commands such as ``console orm:schema-tool:update`` (see #979).

With this change, metadata entries fetched from cache are checked for freshness using a quick last modified check. This is much faster than loading the actual metadata using the metadata driver. This allows you to enable the metadata cache during development without the need for manually flushing the metadata cache.

This PR is part 1 of 2. Part 2 is for the doctrine/common repository.

If this PR is accepted, it allows us to optimize the auto-generate proxy classes feature by comparing the last modified time for the metadata with the modified timestamp of the generated file.



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-986] was labeled:
https://github.com/doctrine/doctrine2/pull/986





[DDC-2973] [GH-949] Add a default lock mode to the EntityManager Created: 10/Feb/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of BenMorel:

Url: https://github.com/doctrine/doctrine2/pull/949

Message:

Following [this discussion](https://groups.google.com/forum/#!topic/doctrine-dev/xKGzQcDkilE) on the mailing list, this is a first draft of a proposal to introduce a default lock mode for all entities loaded through an EntityManager.

At the moment, there is no way to set a lock mode for the following use cases:

  • Proxies obtained through `getReference()` and then initialized
  • Entities lazy-loaded through traversal of associations

This proposal introduces the idea of a default lock mode, which can be set at runtime when all reads in a transaction should be locking.

It works this way:

$em->beginTransaction();
$em->getConfiguration()->setDefaultLockMode(LockMode::PESSIMISTIC_WRITE);

// load entities from EntityManager, Repositories or DQL, traverse associations, etc.
// all these entities will be loaded with the given lock mode

$em->commit();
$em->getConfiguration()->setDefaultLockMode(null);

I have successfully tested it with the following use cases:

  • `EntityManager::find()`
  • `EntityRepository::findBy()`
  • DQL queries
  • Proxies
  • Lazy-loaded collections through OneToMany and ManyToMany associations

Before moving forward and writing proper unit tests, I'm looking for your feedback on this proposal. Is this a concept you would be happy to integrate in Doctrine?

If yes, I have a doubt as regards to where the default lock mode should be set: @Ocramius suggested to set it on the `Configuration`; this looked reasonable at first glance, and I have implemented it this way for now. It feels a tiny bit wrong though now that I see it, as I feel like the contents of the Configuration should should only be set during bootstrapping, rather than being set and reset in the controllers as in the example above. I might be wrong obviously.

My suggestion would be to move the default lock mode to the EntityManager, so that the code would become:

$em->beginTransaction();
$em->setDefaultLockMode(LockMode::PESSIMISTIC_WRITE);

Happily waiting for your feedback!



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-949] was labeled:
https://github.com/doctrine/doctrine2/pull/949

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-949] was labeled:
https://github.com/doctrine/doctrine2/pull/949





[DDC-2940] [GH-922] Two hooks for DoctrineBundle to allow ContainerFilterCollection Created: 29/Jan/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of nicoschoenmaker:

Url: https://github.com/doctrine/doctrine2/pull/922

Message:

Allows the DoctrineBundle to inject a ```ContainerFilterCollection``` that creates filters through dependency injection. See doctrine/DoctrineBundle#245.

Would prefer to inject the ```FilterCollection``` into the constructor of the em, but since they have a cyclic dependency I chose setter injection.



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-922] was labeled:
https://github.com/doctrine/doctrine2/pull/922

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-922] was labeled:
https://github.com/doctrine/doctrine2/pull/922





[DDC-2785] spl_object_hash_collisions Created: 08/Nov/13  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: flack Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Ubuntu 12.04



 Description   

After reading DDC-1896 and DDC-136, I'm not exactly sure if this qualifies as a bug, but anyways, here's my code to reproduce:

    public function test_hash_collision()
    {
        $counter = 0;
        do
        {
            $object = $this->create_object();
            $counter++;
            if ($counter > 1000)
            {
                //mark as skipped ? (I never hit this on PHP 5.3 at least)
                break;
            }
        }
        while ($object === false);

        // This fails with "Failed asserting that 1 matches expected 2."
        $this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($object));
    }

    private function create_object()
    {
        static $hashes = array();
        $phone = new CmsPhonenumber();
        $phone->phonenumber = "1234";
        $hash = spl_object_hash($phone);
        $this->_em->persist($phone);

        if (!array_key_exists($hash, $hashes))
        {
            $hashes[$hash] = true;
            $this->_em->flush($phone);
            $this->_em->remove($phone);
            $this->_em->flush($phone);
            return false;
        }
        // Bingo! We have a new object with a recycled hash
        return $phone;
    }


 Comments   
Comment by Marco Pivetta [ 08/Nov/13 ]

Are you able to reproduce the test also without statics?

Comment by flack [ 08/Nov/13 ]

Yes, if I switch to $this->hashes (private $hashes = array()), the result is the same

Comment by flack [ 08/Nov/13 ]

Here's the complete test without statics & according to Doctrine CS (AFAICT):

<?php

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\Tests\Models\CMS\CmsPhonenumber;

require_once __DIR__ . '/../../../TestInit.php';

/**
 * @group DDC-2785
 */
class DDC2785Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
    public function setUp()
    {
        $this->useModelSet('cms');
        parent::setUp();
    }

    private $hashes = array();

    public function testIssue()
    {
        $counter = 0;
        do
        {
            $object = $this->createObject();
            $counter++;
            if ($counter > 1000)
            {
                //mark as skipped ? (I never hit this on PHP 5.3 at least)
                break;
            }
        }
        while ($object === false);

        $this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($object));
    }

    private function createObject()
    {
        $phone = new CmsPhonenumber();
        $phone->phonenumber = "1234";
        $hash = spl_object_hash($phone);
        $this->_em->persist($phone);

        if (!array_key_exists($hash, $this->hashes))
        {
            $this->hashes[$hash] = true;
            $this->_em->flush();
            $this->_em->remove($phone);
            $this->_em->flush();
            return false;
        }

        return $phone;
    }
}

I can try and send this as a pull request, if it helps

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-843] was labeled:
https://github.com/doctrine/doctrine2/pull/843





[DDC-2786] [GH-843] Add failing test for DDC-2785 Created: 08/Nov/13  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of flack:

Url: https://github.com/doctrine/doctrine2/pull/843

Message:

Add a failing test for

http://www.doctrine-project.org/jira/browse/DDC-2785



 Comments   
Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-843] was labeled:
https://github.com/doctrine/doctrine2/pull/843





[DDC-2524] Wrong commit order with cascade remove and double association Created: 24/Jun/13  Updated: 24/Jan/15

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Matthieu Napoli Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: None


 Description   

We have stumbled upon a bug in a situation where a class A has the following associations to a class B:

  • A has one B (oneToOne unidirectional)
  • A has many B (oneToMany bidirectional)

Associations are with cascade remove.

We will submit a PR soon with a failing test case.

The failure is a MySQL foreign key violation exception when removing A (removals for B are executed after removals for A).



 Comments   
Comment by Valentin Claras [ 24/Jun/13 ]

Here a link to the pull request https://github.com/doctrine/doctrine2/pull/707

Comment by Matthieu Napoli [ 25/Jun/13 ]

The tests on Travis are failing as expected.

https://travis-ci.org/doctrine/doctrine2/builds/8382962

Here is the list of the queries executed for MySQL:

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`doctrine_tests`.`CascadeRemoveOrderEntityG`, CONSTRAINT `FK_23681E8F99938CE5` FOREIGN KEY (`ownerO_id`) REFERENCES `CascadeRemoveOrderEntityO` (`id`))

With queries:

13. SQL: 'DELETE FROM CascadeRemoveOrderEntityO WHERE id = ?' Params: '1'
12. SQL: '"START TRANSACTION"' Params: 
11. SQL: 'SELECT t0.id AS id1, t0.ownerO_id AS ownerO_id2 FROM CascadeRemoveOrderEntityG t0 WHERE t0.ownerO_id = ?' Params: '1'
10. SQL: 'SELECT t0.id AS id1, t0.oneToOneG_id AS oneToOneG_id2 FROM CascadeRemoveOrderEntityO t0 WHERE t0.id = ?' Params: '1'
9. SQL: '"COMMIT"' Params: 
8. SQL: 'INSERT INTO CascadeRemoveOrderEntityG (ownerO_id) VALUES (?)' Params: '1'
7. SQL: 'INSERT INTO CascadeRemoveOrderEntityO (oneToOneG_id) VALUES (?)' Params: ''
6. SQL: '"START TRANSACTION"' Params: 

As you can see, the latest query causes a foreign key constraint violation (wrong order with the next, non-executed query).

Comment by Matthieu Napoli [ 25/Jun/13 ]

On the sqlite tests we can see better the order the queries are executed:

14. SQL: 'DELETE FROM CascadeRemoveOrderEntityG WHERE id = ?' Params: '1'
13. SQL: 'DELETE FROM CascadeRemoveOrderEntityO WHERE id = ?' Params: '1'
12. SQL: '"START TRANSACTION"' Params: 
11. SQL: 'SELECT t0.id AS id1, t0.ownerO_id AS ownerO_id2 FROM CascadeRemoveOrderEntityG t0 WHERE t0.ownerO_id = ?' Params: '1'
10. SQL: 'SELECT t0.id AS id1, t0.oneToOneG_id AS oneToOneG_id2 FROM CascadeRemoveOrderEntityO t0 WHERE t0.id = ?' Params: '1'
9. SQL: '"COMMIT"' Params: 
8. SQL: 'INSERT INTO CascadeRemoveOrderEntityG (ownerO_id) VALUES (?)' Params: '1'
7. SQL: 'INSERT INTO CascadeRemoveOrderEntityO (oneToOneG_id) VALUES (?)' Params: ''
6. SQL: '"START TRANSACTION"' Params: 

13 and 14 are in the wrong order.

Comment by Guilherme Blanco [ 03/Aug/13 ]

This situation is not supported and cannot be resolved within current Doctrine code.
You created a circular dependency between the entities A and B. It happened because A contains one B (oneToOne) and because B contains a pointer to A as part of oneToMany association.
That way, you'll always have a foreign key constraint issue from RDBMS, no matter which entity you try to remove first.

Because of that, I'mm marking this ticket as "can't fix".

Comment by Matthieu Napoli [ 05/Aug/13 ]

Guilherme Blanco I see what you mean, but the case we submitted is with a nullable foreign key. So the operation is permitted by the RDBMS.

A has one B (nullable oneToOne), and B has a pointer to A (manyToOne, not nullable).

As I said for the query log, B should be removed first, which is not the case (see above, line 13 and 14 should be inversed).

So this is fixable on the Doctrine side if I'm not mistaken.

Comment by Benjamin Eberlei [ 03/Jan/14 ]

Matthieu Napoli is this fixed with your DDC-2775 PR?

Comment by Matthieu Napoli [ 15/Jan/14 ]

Just for clarity (I answered this question in the pull request): no this is not fixed (see https://github.com/doctrine/doctrine2/pull/707#issuecomment-31564035).

Comment by Benjamin Morel [ 04/Dec/14 ]

Just encountered what I believe to be the same bug, without any kind of circular dependency:

class A {
    /**
     * @ORM\OneToMany(targetEntity="B", mappedBy="a", indexBy="x", cascade={"all"}, orphanRemoval=true)
     */
    private $b;

    ...
}

class B {
    /*
     * @ORM\ManyToOne(targetEntity="A", inversedBy="b")
     * @ORM\JoinColumn(name="aid", referencedColumnName="id", nullable=false, onDelete="CASCADE")
     */
    private $a;

    ...
}

The following operations in A:

$this->b->clear();
$this->b->add(new B());

Result in the following SQL commands:

INSERT INTO B ...
DELETE FROM B ...

This is always the wrong commit order, and is doomed to fail when you have unique constraints in the B table.

Comment by Maxim Kapkaev [ 19/Dec/14 ]

Another situation without circular dependency:

class Entity
{
    /**
     * @ORM\OneToMany(targetEntity="Picture", mappedBy="entity", fetch="EXTRA_LAZY", cascade={"all"}, orphanRemoval=true)
     * @ORM\OrderBy({"position" = "ASC"})
     */
    protected $pictures = array();
} 

class Pictures {
    /**
     * @ORM\Column(type="string", length=1024, unique = true)
     */
    protected $file;
}
$hotel->setPictures($picturesArray);
$em->flush();
$hotel->getPictures()->clear();
$hotel->setPictures($somePictureUpdatedArray);
$em->flush();
Unique violation: 7 ERROR:  duplicate key value violates unique constraint "uniq_8f7c2fc08c9f3610"

Why we can't invoke entity deletions method (executeDeletions, UnitOfWork#commit) before executeInserts?
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L385-L388
There is another way?

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-707] was labeled:
https://github.com/doctrine/doctrine2/pull/707





[DDC-2363] Duplicated record with orphanRemoval and proxy Created: 22/Mar/13  Updated: 24/Jan/15

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Manuele Menozzi Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orphanRemoval, proxy
Environment:

Tested both Mac OS X and Ubuntu


Issue Links:
Duplicate
is duplicated by DDC-2364 [GH-625] [DDC-2363] Duplicated record... Open

 Description   

There is a problem that causes duplicate records are created when EntityManager has to remove an entity due to orphanRemoval. The problem occurs only with a double flush and referred object is a proxy.

I'm trying to submit a pull request for this ticket. Please, stand by.



 Comments   
Comment by Marco Pivetta [ 27/Mar/14 ]

Hey Manuele Menozzi, do you remember if this has been fixed? Are you still able to reproduce the problem?

Comment by Manuele Menozzi [ 27/Mar/14 ]

Hi Marco,
I made a PR (https://github.com/doctrine/doctrine2/pull/625) with an automated test that reproduce the problem. I just ran this test over latest version of doctrine2 and it's still failed. So, the problem has not be fixed and I (or you) can reproduce it easily.

Let me know if I can help you somehow.

Comment by Marco Pivetta [ 27/Mar/14 ]

Thanks, didn't see it!

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-625] was labeled:
https://github.com/doctrine/doctrine2/pull/625





[DDC-2364] [GH-625] [DDC-2363] Duplicated record with orphanRemoval and proxy Created: 22/Mar/13  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates DDC-2363 Duplicated record with orphanRemoval ... Awaiting Feedback

 Description   

This issue is created automatically through a Github pull request on behalf of mmenozzi:

Url: https://github.com/doctrine/doctrine2/pull/625

Message:

See http://www.doctrine-project.org/jira/browse/DDC-2363.



 Comments   
Comment by Doctrine Bot [ 30/Jun/14 ]

A related Github Pull-Request [GH-625] was closed:
https://github.com/doctrine/dbal/pull/625

Comment by Doctrine Bot [ 24/Jan/15 ]

A related Github Pull-Request [GH-625] was labeled:
https://github.com/doctrine/doctrine2/pull/625





[DDC-3341] SessionValidator gives an error message on orderBy association, but it is no error. Created: 07/Oct/14  Updated: 24/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: Tobias Feijten Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orderBy, orm


 Description   

For @OrderBy annotations, the \Doctrine\ORM\Tools\SchemaValidator only checks if a field with the designated name exists at the designated Entity.
In the case of ordering on an association, defined in the target Entity, this is of course not the case, rendering an error like "The association Idb\TicketBundle\Entity\Ticket#ticketReservations is ordered by a foreign field ticketreservationtype_id that is not a field on the target entity Idb\TicketBundle\Entity\TicketReservation"
However, the \Doctrine\ORM\Persisters\BasicEntityPersister\getOrderBySQL function perfectly supports associations to order on.
Therefore, the error message should not be given when using an association existing at the designated Entity, as it's working and no mistake.
Could this be fixed?



 Comments   
Comment by Marco Pivetta [ 07/Oct/14 ]

Tobias Feijten provide a failing test case to demonstrate the problem first

Comment by Tobias Feijten [ 07/Oct/14 ]

Idb\TicketBundle\Entity\Ticket

namespace Idb\TicketBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

class Ticket {

  /**
   * @ORM\OneToMany(targetEntity="Idb\TicketBundle\Entity\TicketReservation", mappedBy="ticket", cascade={"persist","remove"})
   * @ORM\OrderBy({"ticketReservationType" = "ASC", "amount" = "DESC"})
   */
  private $ticketReservations;

}

Idb\TicketBundle\Entity\TicketReservation

namespace Idb\TicketBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

class TicketReservation {

  /**
   * @ORM\ManyToOne(targetEntity="Idb\TicketBundle\Entity\TicketReservationType")
   * @ORM\JoinColumn(name="ticketreservationtype_id", referencedColumnName="id")
   */
  private $ticketReservationType;

  /**
   * @var integer
   * @ORM\Column(name="amount", type="integer", nullable=false)
   */
  private $amount;

}

The orderBy on amount gives no error when validating the schema, the orderBy on ticketReservationType does (* The association Idb\TicketBundle\Entity\Ticket#ticketReservations is ordered by a foreign field ticketReservationType that is not a field on the target entity Idb\TicketBundle\Entity\TicketReservation).
However, the orderBy statement is not wrong as it is carried out perfectly when using the code.
The only problem is when validating.

Comment by Tobias Feijten [ 13/Oct/14 ]

Marco Pivetta Any progress on this one yet? Or do you need more information?

Comment by Marco Pivetta [ 13/Oct/14 ]

Any progress on this one yet?

No, no progress so far, and I can't allocate time for D2 over the next few weeks.
As for the information amount, it seems sufficient to me: we are probably just using field mappings without checking association mappings when looking for order fields. There is still a problem about what to do with composite identifiers or derived identifiers, but it should be covered by tests first.

Comment by Tobias Feijten [ 24/Jan/15 ]

Marco Pivetta I'm sorry for asking, but still no progress for this ticket? Any ETA? Half a year would be fine (for instance), just keep us up-to-date.

Comment by Marco Pivetta [ 24/Jan/15 ]

Tobias Feijten I honestly worked on a load of other tickets, but not on this one.

If you want an ETA, start looking into it yourself, as I can't pack it into the 2.5 release myself due to time constraints.





[DDC-3527] Provide a method to retrieve exactly one entity out of entity repository Created: 20/Jan/15  Updated: 22/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: 3.0

Type: Improvement Priority: Minor
Reporter: Dominik D Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hello,

currently we have EntityRepository::findOneBy() method for retrieving a single or none entities out of an EntityRepository. It would be very useful, if there was a method which retrieves exactly one entity or throws NonUniqueResultException in case of multiple records returned or NoResultException in case of zero results returned (just like Query::getSingleResult() currently does).

Very often I find myself creating custom repositories for a couple of ::findOneByOrThrow() methods only. Needless to say it's quite mundane to do. The bodies of such methods follows the same pattern:

1. Query the EntityRepository using EntityRepository::findOneBy().
2. If the result is null, then throw an Exception.
3. Return the result.

It'd be very nice to have it out-of-the-box in the base EntityRepository.

Thanks.



 Comments   
Comment by Marco Pivetta [ 20/Jan/15 ]

We actually want to reduce the repository API, not expand it...

Comment by Dominik D [ 21/Jan/15 ]

Wow, ok. I guess you've got good reasons for it and I shouldn't try to convince you, that having methods for most common use cases out of the box is quite convenient?

If yes, then fine. I can create a common EntityRepository subclass for myself and put any helper methods I want there. This would at least cut down on the code duplication in my codebase.

If what you say is final, then we can close this ticket.

Cheers.

Comment by Marco Pivetta [ 22/Jan/15 ]

I guess you've got good reasons for it and I shouldn't try to convince you, that having methods for most common use cases out of the box is quite convenient?

The main problem is that adding API methods to repositories forces any subclasses to also apply eventual filtering logic to those as well.

Other than that, it's merely a question of interface segregation: the current API is hardly maintainable if we assume that many developers subclassed the EntityRepository class, therefore we should keep it locked until 3.x.

I'll actually mark this issue for 3.0 and defer discussion till then.

Comment by Dominik D [ 22/Jan/15 ]

Ok, thanks.





[DDC-2170] Decorator base classes for query related objects Created: 26/Nov/12  Updated: 22/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Major
Reporter: Lars Strojny Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Doctrine\ORM\Query should not be directly extendable but it would be nice to decorate query objects and add additional methods. Use cases are e.g. doctrine-fun (see https://github.com/lstrojny/doctrine-fun/blob/master/src/Doctrine/Fun/Query.php) or even cases where users want to add domain specific methods. As Doctrine\ORM\Query is final it is not so easy to decorate correctly. I would propose:

  • Add a new interfaces: Doctrine\ORM\QueryInterface that provides a contract for all methods Doctrine\ORM\Query provides
  • Add a decorator base class Doctrine\ORM\QueryDecorator as an extension point
  • Some for NativeQuery and QueryBuilder


 Comments   
Comment by Lars Strojny [ 26/Nov/12 ]

Related:

Comment by Aurimas Niekis [ 21/Jan/15 ]

Any changes on this?

Comment by Marco Pivetta [ 22/Jan/15 ]

The EntityManagerInterface now allows producing custom query objects: just requires a custom createQuery or createQueryBuilder API.

Comment by Aurimas Niekis [ 22/Jan/15 ]

Yes, but you can't extend `Doctrine\ORM\Query` object, and many places expects `Doctrine\ORM\Query` not your custom query object

Comment by Marco Pivetta [ 22/Jan/15 ]

Oh, I see what you mean.

Yes, those still require patching, so I suggest getting your hands dirty and trying with a pull request





[DDC-3525] Exception "The column id must be mapped to a field in class" when associationKey used Created: 20/Jan/15  Updated: 21/Jan/15

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.7
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Ilya Antipenko Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: associationKey, foreign-key

Attachments: Text File foreign-key.log    

 Description   

I have issue when I use "associationKey"

I create test repo for reproduce this issue:
https://github.com/aivus/symfony2-foreign-bug

1. composer install
2. Set DB parameters in app/config/parameters.yml and create DB
3. php app/console doctrine:schema:create --force
4. php app/console server:run
5. Load fixtures: http://127.0.0.1:8000/app/loadFixture
6. Try to get list: http://127.0.0.1:8000/app_dev.php/admin/app/app/order/list

I make workaround, which works for me (https://github.com/aivus/doctrine2/commit/8461111e8aea98d02175f3642870a689d446beef), but I'm not sure about it



 Comments   
Comment by Ilya Antipenko [ 21/Jan/15 ]

Add stacktrace





[DDC-3215] wrong quotation Created: 16/Jul/14  Updated: 20/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: revrev Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: dql, orm


 Description   

when doctrine build query´s, for example when you doing

$entitity->getTest()->clear();

following queries are generated (test_id is integer in mysql):

DELETE FROM test WHERE test_id = '6'

Is this right?
For me the right query would be:

DELETE FROM test WHERE test_id = 6

as in http://dev.mysql.com/doc/refman/5.5/en/type-conversion.html
6 will be converted to float, this can be an issue, or?

Comparisons that use floating-point numbers (or values that are converted to floating-point numbers) are approximate because such numbers are inexact. This might lead to results that appear inconsistent:

mysql> SELECT '18015376320243458' = 18015376320243458;
        -> 1
mysql> SELECT '18015376320243459' = 18015376320243459;
        -> 0

this also happens in dql sometimes, why doctrine does this not automatic right due to description in the entities?

     /**
     * @ORM\Id @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */


 Comments   
Comment by Marco Pivetta [ 16/Jul/14 ]

Could you please convert this to a failing test case? Doctrine doesn't quote integers as strings by default.

Comment by revrev [ 16/Jul/14 ]

i try to describe what i have done

i have an Entity with:

    /**
     * @ORM\ManyToMany(targetEntity="Messen", inversedBy="vertrag_messen")
     * @ORM\JoinTable(name="vertrag_messen")
     **/
    private $vertrag_messen;

    public function __construct()
    {
        $this->vertrag_messen = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function getMessen()
    {
        return $this->vertrag_messen;
    }

when i now clear the Data

$entitity->getMessen()->clear();

following query is created
DELETE FROM vertrag_messen where messe_id = '6'

Should here not set the value 6 as integer (param_int) (DELETE FROM test vertrag_messen where messe_id = 6) that mysql doesn´t have to cast the value? (http://dev.mysql.com/doc/refman/5.5/en/type-conversion.html) or is this not an problem?

Comment by Marco Pivetta [ 16/Jul/14 ]

is messe_id in your entity an integer or a string at the moment in time when that query is being executed?

Comment by revrev [ 16/Jul/14 ]

the value comes automatic
$entitity = $em->getRepository('Base\Entities\Vertrag')>find(intval($data["id"]));

i don´t set messe_id here

Comment by Marco Pivetta [ 16/Jul/14 ]

Can you var_dump the Base\Entities\Messe instance?

Comment by revrev [ 16/Jul/14 ]

object(stdClass)#1014 (64) {
["__CLASS__"]=>
string(24) "Base\Entities\Vertrag"
["id"]=>
int(6)
[„vertrag_messen"]=>
array(1)

Unknown macro: { [0]=> string(20) "BaseEntitiesMessen" }


["erstellungsdatum"]=>
object(stdClass)#1210 (3)

Unknown macro: { ["__CLASS__"]=> string(8) "DateTime" ["date"]=> string(25) "2013-09-28T00}

["zeitraumvon"]=>
NULL
["zeitraumbis"]=>
NULL
["jahr"]=>
int(2014)
["created"]=>
object(stdClass)#1178 (3)

Unknown macro: { ["__CLASS__"]=> string(8) "DateTime" ["date"]=> string(25) "2013-09-28T19}

["updated"]=>
object(stdClass)#1177 (3)

Unknown macro: { ["__CLASS__"]=> string(8) "DateTime" ["date"]=> string(25) "2014-07-16T17}

["uuid"]=>
string(36) "52470c58-4288-45eb-b75f-0c41c0a81437"
}

Comment by Marco Pivetta [ 17/Jul/14 ]

yeah, integer identifier there.
Could you verify if the problem also comes up with current master? I think this issue is related with another one that was fixed some months ago in 2.5.x-dev

Comment by Mathias Dietrich [ 20/Jan/15 ]

@Marco Pivetta:

I was affected by exact the same issue. Even when running git master at the beginning of last week, it was still broken.
Today I retestet. Luckily your latest commits (from beginning with: 445798ed46291f2639b3657142bd2f934d1be8a6) to the BasicEntityPersister seemed fixed it.

@revrev:
Could you please retest your example? This bug might be fixed. Thx.





[DDC-3512] Redesign ClassMetadata API as ValueObject based (for type-safety and self-documentation) Created: 17/Jan/15  Updated: 18/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers, ORM
Affects Version/s: None
Fix Version/s: 3.0
Security Level: All

Type: Improvement Priority: Critical
Reporter: Marco Pivetta Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: classmetadatafactory, cleanup, metadata, performance, type-safety

Issue Links:
Reference
relates to DDC-3503 [GH-1257] Resolve target entity also ... Resolved

 Description   

The current ClassMetadata API is based on a lot of array juggling (for performance reasons).

While that was understandable with PHP 5.3, all the array access operations are currently:

  • slowing things down
  • making the code very hard to read/understand

I suggest re-coding the ClassMetadata internals (public properties and such) so that well-described properties are defined.

Additionally, as a bonus, we'd get a performance boost by just moving all the class-alias and type resolution logic from the runtime into the ClassMetadataFactory (or similar) API, saving tons of performance at every run.

In pseudo-logic, what I'd like to achieve with DDC-3512 is:

  • base metadata is loaded from the mapping driver
  • onLoadMetadata event is fired for each loaded metadata instance
  • metadata is completed by the ClassMetadataFactory logic
  • onCompleteMetadata event is fired for each loaded metadata instance

This would make metadata manipulation from events a bit messier (user needs to know which value to change during which event), but would allow using better constrained metadata structures in future, and that would disallow mistakes during event listeners execution as well (internal validation).






[DDC-349] Add support for specifying precedence in joins in DQL Created: 18/Feb/10  Updated: 17/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.0-ALPHA4
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Dennis Verspuij Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File DDC349Test.patch    
Issue Links:
Duplicate
is duplicated by DDC-1256 Generated SQL error with DQL WITH and... Resolved
Reference
is referenced by DDC-3500 [GH-1254] Fix applying ON/WITH condit... Resolved

 Description   

This request is in followup to my doctrine-user message "Doctrine 2.0: Nested joins'.
I am a bit surprised by the responses in that defining precedences in joins by placing parenthesis around join expressions is not well-known. Although not in the original SQL92 specification it is a major and important feature offered by all the RDBMS's that Doctrine 2 supports, and oftenly performs better than using subselects or alike. Doctrine 1 did not support it, but imho Doctrine 2 should support it to be a mature allround ORM.

As a short example the following is a SQL statement with a nested join, where the nesting is absolutely necessary to return only a's together with either both b's and c's or no b's and c's at all:

SELECT *
FROM a A
LEFT JOIN (
b B
INNER JOIN c C ON C.b_id = B.id
) ON B.a_id = A.id

In order for Doctrine 2 to support this the BNF should be something like:
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" ( "(" JoinAssociationPathExpression ["AS"] AliasIdentificationVariable Join ")" | JoinAssociationPathExpression ["AS"] AliasIdentificationVariable ) [("ON" | "WITH") ConditionalExpression]
instead of the current:
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression]

This would allow DQL like:

SELECT A, B, C
FROM a A
LEFT JOIN (
A.b B
INNER JOIN B.c C
) WITH B.something = 'value' AND C.something = 'othervalue'

What further needs to be done is that the DQL parser loosly couples the ConditionalExpression to any of the previously parsed JoinAssociationPathExpression's instead of tieing it explicitely to the JoinAssociationPathExpression that preceedes it according to the old BNF notation. The new BNF should however not require any changes to the hydrator. Therefore I have the feeling that improving the DQL parser for nested joins does not require extensive work, while the benefit of running these kind of queries is considerable.

As an extra substantiation here are links to (BNF) FROM clause documentations of the RDBMS's that Doctrine 2 supports, they all show support for nested joins:
MySQL: http://dev.mysql.com/doc/refman/5.0/en/join.html
PostgreSQL: http://www.postgresql.org/docs/8.4/interactive/sql-select.html#SQL-FROM and http://www.postgresql.org/docs/8.1/interactive/explicit-joins.html
MSSQL: http://msdn.microsoft.com/en-us/library/ms177634.aspx
Oracle: http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/statements_10002.htm#CHDDCHGF
SQLite: http://www.sqlite.org/syntaxdiagrams.html#single-source

I surely hope you will consider implementing this improvement because it would save me and others from the hassle of writing raw SQL queries or executing multiple (thus slow) queries in DQL for doing the same. Thanks anyway for the great product so far!



 Comments   
Comment by Guilherme Blanco [ 13/Apr/10 ]

This seems to be a valid issue to me.

This implementation is the actual solution to associations retrieval that are inherited (type joined).

Example:

/** Joined */
class Base {}

class Foo extends Base {}

class Bar {
    public $foo;
}

// This causes the CTI to link as INNER JOIN, which makes the result become 0
// il if you have no Foo's defined (although it should ignore this)
$q = $this->_em->createQuery('SELECT b, f FROM Bar b LEFT JOIN b.foo f'); 
Comment by Roman S. Borschel [ 13/Apr/10 ]

Yes, this is a possible solution for DDC-512 but on the SQL level. I still don't see this as appropriate for DQL, it just doesnt make sense to me, DQL joins object associations, there is no precedence.

Comment by Roman S. Borschel [ 13/Apr/10 ]

So, no, this has nothing to do with DDC-512. DDC-512 can even be fixed differently as outlined in my comments there.

Comment by Roman S. Borschel [ 13/Apr/10 ]

On a side note I would still like to know/see the following for this issue:

  • Some realisitic DQL examples where this feature would be essential, i.e. there is no other way to do it.
    This also means explaining what the impact on the resulting object graph is and why it makes sense.
  • Which other ORMs support this on the OQL/Criteria level?

So far, my stance on this issue is:

1) It doesnt make sense (semantically) in DQL
2) Its rarely needed
3) When you really need it you can use a NativeQuery anyway and use this nesting in SQL, where it probably belongs and makes more sense
4) It would (unnecessarily) complicate DQL

Thus I am currently leaning towards "Wont fix" for this issue.

Comment by Dennis Verspuij [ 13/Apr/10 ]

Hi Roman. I understand your doubts, and I have been breaking my head over
creating a realistic example the last few hours that would hopefully convince
you for implementing this feature. But actually I cannot find one that you wouldn't
consider to be trivial. I do have a number of very complex optimized queries written
for sportskickoff dot com (using Doctrine 1.2) but they are probably hard to understand
because they may not be selfdescribing. Below is one example literally ripped from
the application. Still they often can be broken down to my example query in this
ticket's description, but applied grouping, additional other joins on the root component
and/or other criteria made them impossible to rewrite using subselects or choosing
another root component. Most often they just performed way best using the nested
syntax and saved me a number of additional queries.

SELECT A.id, A.username, A.balance, COALESCE(SUM(B.stake), 0) AS sumstake, COUNT(B.id) AS nrbets
FROM account A
LEFT JOIN (
bet B
INNER JOIN game G ON G.id = :GAMEID AND B.timestampcompletion BETWEEN G.timestampstart AND G.timestampend
) ON B.accountid = A.id AND B.timestampcompletion IS NOT NULL
WHERE A.Status & :ACTIVEORDISQUALIFIED = :ACTIVE
GROUP BY A.id, A.username, A.balance
ORDER BY A.balance DESC, sumstake ASC, nrbets ASC, A.username ASC

But let's put it another way. I would also like this feature to be supported in DQL
because I just do not want to use native queries. Why would I want to use native
queries if it can be done using DQL? In DQL I work with class names and field
names, and they may differ from the underlying table and column names. Doctrine
takes care of that mapping based on my schema/annotations and I do not
have to "know" these mappings. In native queries I suddenly do have to "know"
these mappings. I use Doctrine because it makes my application portable and
enables me to work with my database in an OOP way like I do in my model,
abstracting things. The need for native queries partly reverts the benefits Doctrine
offers in the first place.

Btw, I recall to have successfully used the nested join syntax in HQL (.NET Hibernate)
but I cannot find examples on the web or a BNF notation.

Furthermore, in reply to your stances:
1) It indeed doesnt make sense (semantically) in DQL, it only makes the result
set different, but not the way data is hydrated into objects;
2) Its indeed rarely needed for inserting, updating and populating basic lists but
it allows you to better select what combinations of associated rows are joined
and which not in more optimized queries without having to use native queries,
or because they perform better than using subseletcs and alike.
3) Not having to use native queries is just an extra reason for using Doctrine and
maintains the abstraction the ORM provides througout on'es whole application
4) Why would it complicate DQL, if people do not know about or understand
the feature it wouldn't matter because not using parenthesises is the default
way to specify joins?

Well, this is it, can't find any more words to promote and make you enthusiastic.... lol.

Comment by Dennis Verspuij [ 13/Apr/10 ]

Ok, I have not given up yet... , here's a "stupid" example.

Imagine a book store that sells books of various authors and keeps track of those sales.
Let's say you would have an admin page that lists all authors, and for each author
its also shows the books and their sales dates since january 1st, but only for those
books that were actually sold and contain an A in its name. An optimized SQL query
to fetch all the information at once would be something like:

SELECT A., B., S.*
FROM author A
LEFT JOIN (
book B
INNER JOIN sale S ON S.book_id = B.id AND S.dt >= '2010-01-01'
) ON B.author_id = A.id AND A.name LIKE '%A%'

In DQL it would then be something like:

SELECT A., B., S.*
FROM author A
LEFT JOIN (
book B
INNER JOIN sale S WITH S.dt >= '2010-01-01'
) WITH A.name LIKE '%A%'

If the database would contain thousands of books, but sales for just a
few books, this will definitely perform better than using subselects.
Off course one would like to fetch array graphs instead of objects for
further optimization, but this hopefully shows my point.

I have attached a test casefor a similar query, though without the additional
join constraints for clarity. I surely hope you can consider it.

One last note, you shouldn't be afraid that nesting joins is not in the
ansi SQL spec. Select queries are about record sets and products
between these sets, tables are just the basic means of providing record
sets to the query. This is an important terminological difference to think about.
Specifying precedence with parenthesis around joins is a logical and
natural evolution of the ansi sql standard. For example views are a good
proof of this concept, I could define book B INNER JOIN sale S as a view
and LEFT JOIN that to authors to get effectively the same result
set as the above example. The database server would internally perform the
same query (though may additionally take indexes on the view into account).
That said, rdbm's that support this syntax would certainly never drop the
feature, as its not a feature but just plain logical and smart querying!

P.S. I had a hard time finding out how to run the test cases, I could not find
it in the Doctrine 2 documentation, development wiki, cookbook or any other
place, while finally it was as easy as running phpunit Doctrine_Tests_AllTests
from within the tests/ directory, or just phpunit Doctrine_Tests_ORM_Functional_Ticket_DDC349Test
for my test. Could you please add some info about this somewhere, it might
save others some googling.

Comment by Dennis Verspuij [ 13/Apr/10 ]

Test case as SVN patch using a parenthesized join.
Just remove the parenthesises from the query to have it fail...

Comment by Roman S. Borschel [ 29/May/10 ]

@"The need for native queries partly reverts the benefits Doctrine offers in the first place."

That is something I hugely disagree with. Neither SQL abstraction, nor database vendor independence is the main purpose of an ORM like Doctrine 2.
It is the state management of your objects, the transparent change tracking, lazy-loading and synchronization of the object state with the database state and nothing of this gets lost when using native queries.

We could rip out DQL and any other querying mechanism except a basic find() (and lazy-loading, of course), only providing the native query facility and even only supporting MySQL and would still retain all the core ORM functionality.

NativeQuery is one of the best and core "features" of the project. It is even the foundation for DQL. A DQL query is nothing more than an additional (beautiful) abstraction but what comes out is a native query + a ResultSetMapping, the same thing you can build yourself in the first place, even using the mapping metadata to construct the query. Nothing forces you to hardcode table and column names in native queries if you don't want that. Just use the mapping metadata, DQL does the same.

SQL abstraction and database vendor independence is icing on the cake, not the heart of the ORM.





[DDC-3416] using getArrayResult and foreach with reference get a string at the end Created: 26/Nov/14  Updated: 17/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.6
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: sysko Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

doctrine2 alone, not inside symfony or any framework



 Description   

This bug is quite weird so let me explain it

I have 2 Entity

Category (language independant information)

CategoryDescription (language dependant category 1 -> N categoryDescription)

when i do

        $categories = $this->createQueryBuilder('Entity\Category')
            ->select('c')
            ->distinct()
            ->from('Entity\Category', 'c')
            ->getQuery()
            ->getArrayResult();
        ;

        foreach ($categories as &$category) {
            var_dump($category);
            $plop = $category['id'];
        }

I will get the last element of the array as a string instead of an array
and that string being the value of the column "name" of the last CategoryDescription in my database

using a normal foreach without reference does not trigger the bug
using getResult also does not trigger the bug

if needed and someone guide me I can try to furnish a "minimal code" to reproduce the issue



 Comments   
Comment by Claudio [ 17/Jan/15 ]

Does CategoryDescription contain a __toString() method?





[DDC-2570] Doctrine CLI Tools - Clear All Cache Created: 24/Jul/13  Updated: 17/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM, Tools
Affects Version/s: 2.3.4
Fix Version/s: 2.x

Type: Improvement Priority: Minor
Reporter: Frederick Marcoux Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: Cli, cache, orm


 Description   

It would be nice to be able to clear all cache one shot instead of clearing them one after one...

Like this:

root$ ./doctrine orm:clear-cache:all

Instead of:

root$ ./doctrine orm:clear-cache:metadata
root$ ./doctrine orm:clear-cache:result
root$ ./doctrine orm:clear-cache:query






[DDC-1599] OnFlush event in transaction Created: 14/Jan/12  Updated: 17/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: 3.0

Type: Improvement Priority: Major
Reporter: Gediminas Morkevicius Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 3
Labels: None


 Description   

Is there any particular reason why onFlush event is not triggered when the transaction is allready open? https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L290 It would help a lot developing listeners since this event is the mostly used one and since theres preFlush now it seems a logical solution if onFlush would be a start of transaction in general



 Comments   
Comment by Benjamin Eberlei [ 14/Jan/12 ]

onFluish is not the start of a transaction. It has nothing to do with this.

Comment by Marco Pivetta [ 31/Mar/12 ]

Is a third event needed? Or is this to be marked as "won't fix"?

Comment by Benjamin Eberlei [ 31/Mar/12 ]

Maybe onBeginTransaction, onCommit and onRollback.

However since you can start transactions manually using $em->beginTransaction(), the Flush events are somehwat independent of transactions anyways.

Comment by Gediminas Morkevicius [ 31/Mar/12 ]

Well, user can start transaction anytime, but the fact is that if we think ORM we do not know nothing about the database. we just persist and flush objects.

Yes I think these would be very useful, from how I see it, if you use event listeners, is:

loadClassMetadata: you can apply extra mapping

onFlush: you can modify entity changesets, or persist recalculate new ones, without triggering the database, since it is not used to begin the database modifications yet.

onBeginTransaction: could use the database modifications keeping in sync the entity changesets. the thing about this event is that usually in behavioral way atomic updates are required. for example nestedset tree sync lft rgt columns, sortable sync the sort index, materialized path, all these requires atomic updates, and the best place is the start of transaction.

onCommit: could be useful to execute right before commit, finalizing database modifications could be done.

onRollback: this one is really something, since if you go far, there might be something like files uploaded during the entity processing, and you may want to remove them if transaction fails.

Comment by Guilherme Blanco [ 21/May/12 ]

This situation was barely documented here: http://www.doctrine-project.org/jira/browse/DDC-1443

We need a better Transaction API that completely fixes the computation of changesets and also allow more fine grained control over Entities and their corresponding information.

I'd postpone this one until 3.0.





[DDC-1738] Allow multiple Generators per class Created: 29/Mar/12  Updated: 17/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: Git Master
Fix Version/s: 3.0
Security Level: All

Type: Improvement Priority: Major
Reporter: Guilherme Blanco Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We should be able to support multiple generators per class.
When doing partition per table, the partitioned column must be part of PK, which may enter in our limitation.

Currently we only support 1 generator per class.






[DDC-1852] Doctrine\ORM\Tools\SchemaValidator should check validity of lifecycle callbacks Created: 04/Jun/12  Updated: 17/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: 2.x
Security Level: All

Type: Improvement Priority: Major
Reporter: Marco Pivetta Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The schema validator should analyze mapped lifecycle callbacks and:

a) if some lifecycle callbacks were defined, but no @HasLifecycleCallbacks annotation/mapping was set, warn the user
b) if some lifecycle callbacks were defined, but methods are not public, warn the user



 Comments   
Comment by Marco Pivetta [ 04/Jun/12 ]

Existing PR at https://github.com/doctrine/doctrine2/pull/361





[DDC-1963] Remove by-ref access to changeset in lifecycle event args Created: 31/Jul/12  Updated: 17/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: 3.0
Security Level: All

Type: Improvement Priority: Major
Reporter: Marco Pivetta Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None


 Description   

UoW currently passes computed changesets to lifecycle event args byref. This has to be changed to force users to use UoW public API to modify changesets instead.






[DDC-2390] Remove Parser and SQLWalker dependency on Query Created: 04/Apr/13  Updated: 17/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 3.0
Security Level: All

Type: Improvement Priority: Major
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Query is too powerful to be available in Parser and SQLWalker, because it may lead to accessing data that changes on subsequent runs of a query that is cached.

Idea is to introduce a MetadataBag that contains only the values that are allowed to be accessed.






[DDC-3511] Temporarily change fetch mode in DQL for toMany relations Created: 16/Jan/15  Updated: 16/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Major
Reporter: Filip Procházka Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 0
Labels: dql, eager, fetch-mode, query


 Description   

This would be a major improvement. I can't seem to find the issue for this. Is this even planned?

http://docs.doctrine-project.org/en/latest/reference/dql-doctrine-query-language.html#temporarily-change-fetch-mode-in-dql

I might be able to find some time to work on this in February, if nobody else is going to.



 Comments   
Comment by Marco Pivetta [ 16/Jan/15 ]

You might want to wait for the persisters to stabilize with 2.5





[DDC-3349] Possibility to override order of fields of composite ID produced by Mapping Created: 13/Oct/14  Updated: 16/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Major
Reporter: tiger-seo Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mapping

Issue Links:
Reference
relates to DDC-3352 [GH-1162] DDC-3349: Possibility to ov... Resolved

 Description   

So, the problem is when the one needs to use association key in composite identifier; they are added in the end of the identifier array, which is clearly not always suitable in regards to performance.
For example, following mapping:

Acme\DemoBundle\Entity\PageLocalFans:
    type: entity
    id:
        date:
            type: date
        page:
            associationKey: true
        countryCode:
            type: string
            length: 2
    fields:
        fans:
            type: integer
    manyToOne:
        page:
            targetEntity: Page
            joinColumn:
                name: page_id
                referencedColumnName: id
                onDelete: CASCADE

will turn into sql as:

CREATE TABLE page_local_fans (
  date         DATE       NOT NULL,
  country_code VARCHAR(2) NOT NULL,
  page_id      INT        NOT NULL,
  fans         INT        NOT NULL,
  INDEX IDX_7391EB36C4663E4 (page_id),
  PRIMARY KEY (date, country_code, page_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

and there is no way to change the order of the primary from

PRIMARY KEY (date, country_code, page_id)

to

PRIMARY KEY (date, page_id, country_code)


 Comments   
Comment by tiger-seo [ 14/Oct/14 ]

i've done the PR for this, pls see https://github.com/doctrine/doctrine2/pull/1162

Comment by Doctrine Bot [ 17/Oct/14 ]

A related Github Pull-Request [GH-1162] was assigned:
https://github.com/doctrine/doctrine2/pull/1162

Comment by Doctrine Bot [ 16/Jan/15 ]

A related Github Pull-Request [GH-1162] was closed:
https://github.com/doctrine/doctrine2/pull/1162





[DDC-3174] Query Cache not correct working when using SQLFilter Created: 17/Jun/14  Updated: 16/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.1
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Benno Eggnauer Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: cache, sqlfilter


 Description   

We have an SQLFilter to filter on entities with a specific Trait implemented. The filter is very easy:

$res = $targetTableAlias . '.agency_id = ' . $this->getCurrentAgencyId();

On our system we have the query cache enabled, this works as long the "AgencyId" doesn't change. When the ID changes, the query cache seems to return the wrong (old cache) query.



 Comments   
Comment by Marco Pivetta [ 17/Jun/14 ]

I'm not sure if this case should be contemplated by the ORM. Filters are low-level and supposed to be stateless (services).

Comment by Benno Eggnauer [ 17/Jun/14 ]

OK, we can disable the query cache for this case. But then should at least the documentation be updated, which explicitly mentions to use filter for locales, which are also not stateless: http://doctrine-orm.readthedocs.org/en/latest/reference/filters.html#example-filter-class

Also in the query cache chapter: http://doctrine-orm.readthedocs.org/en/latest/reference/caching.html#query-cache

It is highly recommended that in a production environment you cache the transformation of a DQL query to its SQL counterpart. It doesn’t make sense to do this parsing multiple times as it doesn’t change unless you alter the DQL query.

Comment by Marco Pivetta [ 17/Jun/14 ]

Benno Eggnauer can you eventually provide a pull request?

Comment by James Blizzard [ 01/Dec/14 ]

I would just like to say that we're having exactly the same issue. I'd love some method (official or not) of having filters being taken into account in this situation.

Comment by Guglielmo Carandente [ 16/Jan/15 ]

I have the same problem when is generated QueryCacheId It consider only the name of active filters and not the value of the filter
This is the code at line 646 of class \Doctrine\ORM\Query
protected function _getQueryCacheId()

{ ksort($this->_hints); return md5( $this->getDql() . var_export($this->_hints, true) . ($this->_em->hasFilters() ? $this->_em->getFilters()->getHash() : '') . '&firstResult=' . $this->_firstResult . '&maxResult=' . $this->_maxResults . '&hydrationMode='.$this->_hydrationMode.'DOCTRINE_QUERY_CACHE_SALT' ); }




[DDC-3287] PreUpdateEventArgs need to extend Doctrine\Common\PreUpdateEventArgs Created: 29/Aug/14  Updated: 15/Jan/15

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Trivial
Reporter: Sebastian Kuhlmann Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance, orm

Issue Links:
Reference
relates to DDC-3320 [GH-1144] [DDC-3287] Change parent cl... Resolved

 Description   

Currently the inheritance tree of the EventArgs don't allow for creating event listeners that fit both ORM- and MongoDB-driven applications.

Doctrine\Common defines base classes for Lifecycle event arguments. Doctrine\ORM uses the common library and extends it's classes. So does MongoDB. If you wanted to write something that suits both ORM and MongoDB you should be able to rely on the Common-implementations.

The provided classes to extend:

  • Doctrine\Common\Persistence\Event\LifecycleEventArgs
  • Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs
  • Doctrine\Common\Persistence\Event\ManagerEventArgs
  • Doctrine\Common\Persistence\Event\OnClearEventArgs
  • Doctrine\Common\Persistence\Event\PreUpdateEventArgs

Checking the Github repository there is no common ground for the inheritance mechanism.

  • Doctrine\ORM\Event\LifecycleEventArgs extends Doctrine\Common\Persistence\Event\LifecycleEventArgs
  • Doctrine\ORM\Event\PreUpdateEventArgs extends Doctrine\ORM\Event\LifecycleEventArgs
  • Doctrine\ORM\Event\PreFlushEventArgs extends Doctrine\Common\EventArgs
  • Doctrine\ORM\Event\PostFlushEventArgs extends Doctrine\Common\EventArgs
  • Doctrine\ORM\Event\OnFlushEventArgs extends Doctrine\Common\EventArgs
  • Doctrine\ORM\Event\OnClearEventArgs extends Doctrine\Common\EventArgs

This needs to change and ORM\PreUpdateEventArgs as well as ORM\OnClearEventArgs need to extend the respective events from Doctrine\Common.



 Comments   
Comment by Sebastian Kuhlmann [ 23/Sep/14 ]

See https://github.com/doctrine/doctrine2/pull/1144

Comment by Christophe Coevoet [ 04/Oct/14 ]

All flush event args should be updated to extend ManagerEventArgs (and marking their getEntityManager method as deprecated too)

Comment by Christophe Coevoet [ 04/Oct/14 ]

to be clear, the change on PreUpdateEventArgs cannot be done until 3.0 because of BC

Comment by Doctrine Bot [ 19/Oct/14 ]

A related Github Pull-Request [GH-1144] was assigned:
https://github.com/doctrine/doctrine2/pull/1144

Comment by Doctrine Bot [ 15/Jan/15 ]

A related Github Pull-Request [GH-1144] was closed:
https://github.com/doctrine/doctrine2/pull/1144





[DDC-3497] orphanRemoval=true overrides onDelete="CASCADE" behaviour for One-To-Many Bidirectional associations (without Join Table) Created: 14/Jan/15  Updated: 14/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.7
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Alex Prokop Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: cascade, mapping, ondelete, onetomany, orm, orphanRemoval
Environment:

PHP 5.5.11
MySQL 5.6.16 Source distribution


Attachments: File example.php    
Issue Links:
Reference
relates to DDC-3498 orphanRemoval=true for One-To-Many Bi... Open

 Description   

When removing entities from a collection, only the association is removed not the entity itself. But for One-To-Many Bidirectional associations without a Join Table, the database row on the Many-To-One side contains the information for both the association and the entity data. If when removing the association the desired behaviour is to delete the entity as well then orphanRemoval=true can be used on the One-To-Many annotation. However this overrides onDelete="CASCADE" if set on the JoinColumn of the Many-To-One side, resulting in unnecessary DELETE queries. Additionally, these queries are run separately for each entity in the collection, rather than as a single query as with Many-To-Many Join Tables (see linked issue). See example code attached.



 Comments   
Comment by Alex Prokop [ 14/Jan/15 ]

Both issues relate to One-To-Many associations without Join Tables, where the data row on the Many-To-One side is both association and entity data.





[DDC-3498] orphanRemoval=true for One-To-Many Bidirectional associations (without Join Table) produces unnecessary number of DELETE queries Created: 14/Jan/15  Updated: 14/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.7
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Alex Prokop Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mapping, onetomany, orm, orphanRemoval
Environment:

PHP 5.5.11
MySQL 5.6.16 Source distribution


Attachments: File example.php    
Issue Links:
Reference
is referenced by DDC-3497 orphanRemoval=true overrides onDelete... Open

 Description   

If orphanRemoval=true is set on a One-To-Many Bidirectional association without a Join Table, when removing the owning entity, multiple DELETE queries are generated. Since the row in the database on the Many-To-One side contains both the association and entity data, it should be possible to replace this with a single DELETE query using the owning entity's id, as when deleting associations in a Join Table for a Many-To-Many association. See attachment for example code.






[DDC-3491] Annotation for column value case sensitivity Created: 13/Jan/15  Updated: 13/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers, Tools
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Zoltán Halassy Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It would be cool, if CHAR/VARCHAR case-sensitivity could be annotated on a column.

Every database driver would pick two default (config-overridable) collation, one for case-sensitive, and one for case-insensitive, and use those when the user requests or case-sensitive or insensitive column definition. This way the annotation would be portable.






[DDC-3367] [GH-1171] Improvements for complex select statements when using new object expression Created: 28/Oct/14  Updated: 13/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of jaimz22:

Url: https://github.com/doctrine/doctrine2/pull/1171

Message:

My update allows you to alias objects created with the ["new" object expression](http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#new-operator-syntax), as well as the ability to create queries that allow you to have multiple "new" object expressions and mixed scalar results.

Suppose you create a query as such:

```dql
SELECT new UserDTO(u.id,u.name) as user,new AddressDTO(a.street,a.postalCode) as address, a.id as addressId FROM User u INNER JOIN u.addresses a WITH a.isPrimary = true
```

upon executing this query, you'll end up with a result set that looks like the following:

```php
array(
0=>array(
0=>

{UserDTO object},
1=>{AddressDTO object},
2=>{u.id scalar},
3=>{u.name scalar},
4=>{a.street scalar},
5=>{a.postalCode scalar},
'addressId'=>{a.id scalar},
),
...
)
```

My changes fix that so you'd end up with a more usable result set:

```php
array(
0=>array(
'user'=>{UserDTO object}

,
'address'=>

{AddressDTO object}

,
'addressId'=>

{a.id scalar}

)
...
)
```



 Comments   
Comment by Doctrine Bot [ 13/Jan/15 ]

A related Github Pull-Request [GH-1171] was merged:
https://github.com/doctrine/doctrine2/pull/1171





[DDC-3489] Sequence generators should be stateless Created: 13/Jan/15  Updated: 13/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master, 2.4.7
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Marco Pivetta Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: metadata, sequence, sequence-generator, stateless

Issue Links:
Dependency
is required for DDC-2477 [GH-681] Sequence generator fix Resolved

 Description   

Current sequence generators keep internal state such as the metadata of the entity that uses the sequence.

The sequence generators should instead be stateless.






[DDC-3480] ORM\Embeddable does not create ManyToOne column in the database Created: 09/Jan/15  Updated: 11/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Tomas Voslar Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Following Embeddable

/**
 * @ORM\Embeddable
 */
class Address
{
    /**
     * @ORM\ManyToOne(targetEntity="Country")
     */
    protected $country;

won't save country attribute into the database table, other simple attributes (like type="text") saved normally.

    /**
     * @ORM\Embedded(class="LuciniLucini\Adsender\CommonBundle\Entity\Address")
     */
    private $address;


 Comments   
Comment by Marco Pivetta [ 09/Jan/15 ]

The issue seems incomplete to me: what exactly is the failure? Can you make an example?

Comment by Tomas Voslar [ 09/Jan/15 ]

Okay, I am sorry. I have main entity which includes Embeddable entity (Address), this address entity contains country attribute with ManyToOne relation, but this country is not being saved into the database table, other attributes like street (string) are being saved normally.

Comment by Tomas Voslar [ 09/Jan/15 ]

Basically it creates main entity with all fields from embeddable except country which is ManyToOne.

Comment by Marco Pivetta [ 09/Jan/15 ]

Ah, now I get it (I was probably misreading it). We don't support associations from embeddables right now: please check the test suite, but they really don't provide this functionality right now.

Comment by Tomas Voslar [ 09/Jan/15 ]

And is there any chance it will be supported in the near future? Or it's not possible?

Comment by Marco Pivetta [ 09/Jan/15 ]

It will probably not implemented for now, as embeddables (in our vision) are fitting the use-case of ValueObjects. ValueObjects are (usually) supposed to be containing serializable data, and an entity reference is not serializable data.

Comment by Tomas Voslar [ 09/Jan/15 ]

Okay, understood. So it's not good idea to use embeddables for Address entity for example, with this country as relation to another table, right? It seemed to me like best case. Thank you for the support anyway.

Comment by Marco Pivetta [ 09/Jan/15 ]

So it's not good idea to use embeddables for Address entity for example, with this country as relation to another table, right?

I'd rather just save the country identifier in the embeddable instead.

Comment by Tomas Voslar [ 09/Jan/15 ]

So you mean, instead of ManyToOne, save just id=integer (so no relation with entity)?

Comment by Marco Pivetta [ 09/Jan/15 ]

Correct: simple scalar or serializable types

Comment by Tomas Voslar [ 09/Jan/15 ]

https://github.com/doctrine/doctrine2/blob/400acad53355f24137e18d5cd55ccf6ff828cfbe/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php

Line 121 method testDqlOnEmbeddedObjectsField, guess I am wrong, but it seems there should be support for embeddable with relations though.

Comment by Yavin [ 11/Jan/15 ]

Hi,
if is is not supported i think an exception should be thrown when someone use association in embedded class. Now it is just silently ommited.

I found code where embedded metadata is added:
https://github.com/doctrine/doctrine2/blob/573153669c11a6f69201513831d3b8ce5e111d25/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php#L3200





[DDC-3485] Using Embeddable in MappedSuperclass fails Created: 11/Jan/15  Updated: 11/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.5
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Marco Pfeiffer Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File EmbedInMappedSuperclass.php    

 Description   

While Trying to Embed an object into a mapped superclass an exception is thrown:

PHP Fatal error:  Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'Duplicate definition of column 'embed_someField' on entity 'Entity' in a field or discriminator column mapping.' in /home/dev/Workspace/symfony/perto/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php:555





[DDC-3476] JoinTable options are not inherited Created: 06/Jan/15  Updated: 06/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Enrico Schultz Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: join, joins, orm, table-options


 Description   

I'm working with Symfony 2.6 and Doctrine (MySQL), but the error is in the Doctrine 2 ORM.

I have specified a ManyToMany relation like so:

/**
 *@ORM\Table(name="users", options={"engine"="MyISAM", "collate"="utf8_general_ci"})
 * @ORM\Entity
 */
class User
{
  /**
    * @ORM\ManyToMany(targetEntity="Group", inversedBy="users")
    * @ORM\JoinTable(name="user_groups", joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")})
  */
  private $groups;

...
}

All tables should be created as MyISAM and "utf8_general_ci" collation instead of InnoDB and "utf8_unicode_ci". This works fine for all tables except for "user_groups" table because the options are not inherited. As a result the schema is not valid, because foreign keys cannot be created over 2 different collations.

To fix this, I modified class "\Doctrine\ORM\Tools\SchemaTool", function "gatherRelationsSql($class, $table, $schema, &$addedFks, &$blacklistedFks)" and added the following lines in the MANY_TO_MANY block:

if (isset($foreignClass->table['options'])) {
  foreach ($foreignClass->table['options'] as $key => $val) {
    $theJoinTable->addOption($key, $val);
  }
}

Now, it works as I want. The new table is created with the right collation and engine and the foreign keys are created correct. Could you please implement this fix?



 Comments   
Comment by Enrico Schultz [ 06/Jan/15 ]

Please also have a look at DDC-972 where MyISAM support was added. The problem was already mentioned there in the last 4 comments, so it exists at least since 2012.





[DDC-3475] Avoid db connection in constructor Created: 05/Jan/15  Updated: 05/Jan/15

Status: Open
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Stéphane Klein Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Reference
relates to DBAL-1057 Connection is not lazy anymore when g... Open

 Description   

Hi,

Since DBAL 2.5, calling getDatabasePlatform implies in most cases making a connection attempt (https://github.com/doctrine/dbal/blob/master/UPGRADE.md#bc-break-doctrinedbalconnection). Yet that method is called in the constructor of the SchemaTool class, which isn't very clean and can be problematic in some situations.

Are you open to a modification of that class to avoid this issue ? I can think of two workarounds :

  • initializing the platform attribute later
  • removing the attribute, retrieving the platform in getCreateSchemaSql and passing it to subsequent methods

I can send a PR if that's ok for you.



 Comments   
Comment by Steve Müller [ 05/Jan/15 ]

See DBAL-1057.
We still don't know how to properly fix that issue, whether we can do something to make the connection lazier in DBAL already or if we have to adjust ORM / DoctrineBundle and possible other projects to avoid issues.
Currently it looks like we can't do much in DBAL so I tend to say that the complete ORM code has to be scanned for early platform retrieval and fixed to avoid possible issues.
Marco Pivetta Benjamin Eberlei thoughts?





[DDC-2387] convert-mapping not working correctly with composite primary keys/foreign keys in 2.4.0-RC1 Created: 03/Apr/13  Updated: 31/Dec/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.3, 2.3.1, 2.3.2, 2.3.3, 2.3.4
Fix Version/s: 2.3.4
Security Level: All

Type: Bug Priority: Major
Reporter: Nicholas Van Dusen Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 5
Labels: None
Environment:

Symfony 2.2.0, MySQL 5.1



 Description   

(Apologies if this is somehow a Symfony-specific issue)

I updated my application via Composer yesterday, and received Doctrine 2.4.0-RC1. After this update, generating entities has been problematic under certain circumstances.

Here is an example table in MySQL:

CREATE TABLE `user_email` (
  `user_id` int(10) unsigned NOT NULL COMMENT 'FK to user',
  `email` varchar(254) NOT NULL,
  `email_datasource` smallint(1) unsigned NOT NULL COMMENT 'FK to datasource_code',
  `insert_date` datetime NOT NULL,
  PRIMARY KEY (`user_id`,`email`,`email_datasource`),
  KEY `FK_UserEmail_DataSourceCode` (`email_datasource`),
  CONSTRAINT `FK_UserEmail_User` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

In Doctrine 2.3, the mapping works correctly, and you end up with a 3-part primary key, with a user property mapped to the User entity, and a datasourceCode property mapped to the DatasourceCode entity. All good.

In 2.4, the following error is given: Single id is not allowed on composite primary key in entity UserEmail.

Removing one of the foreign keys in the table (either to User or DatasourceCode) but keeping the primary key set to all 3 columns allows the mapping to work. But, if you then remove one of the columns from the primary key (say, email_datasource) it fails again.



 Comments   
Comment by Benjamin Eberlei [ 04/Apr/13 ]

Can you provide the full stack trace to the exception please?

$e->getTraceAsString();
Comment by Nicholas Van Dusen [ 11/Apr/13 ]

Benjamin, I'm not sure how to get the trace for you, since I'm running from inside the Symfony2 doctrine:mapping:import command line item.

Comment by Christophe Coevoet [ 11/Apr/13 ]

Use the --verbose option when running the command

Comment by Nicholas Van Dusen [ 11/Apr/13 ]

I was able to get a trace for you:

#0 /var/www/html/voxrepublic/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php(1571): Doctrine\ORM\Mapping\MappingException::singleIdNotAllowedOnCompositePrimaryKey('UserEmail')
#1 /var/www/html/voxrepublic/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(422): Doctrine\ORM\Mapping\ClassMetadataInfo->getSingleIdentifierFieldName()
#2 /var/www/html/voxrepublic/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(136): Doctrine\ORM\Mapping\ClassMetadataFactory->completeIdGeneratorMapping(Object(Doctrine\ORM\Mapping\ClassMetadata))
#3 /var/www/html/voxrepublic/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(302): Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL, false, Array)
#4 /var/www/html/voxrepublic/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(212): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata('UserEmail')
#5 /var/www/html/voxrepublic/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(112): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor('UserEmail')
#6 /var/www/html/voxrepublic/vendor/doctrine/doctrine-bundle/Doctrine/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php(108): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata()
#7 /var/www/html/voxrepublic/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php(240): Doctrine\Bundle\DoctrineBundle\Command\ImportMappingDoctrineCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#8 /var/www/html/voxrepublic/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(195): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /var/www/html/voxrepublic/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(78): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /var/www/html/voxrepublic/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(106): Symfony\Bundle\FrameworkBundle\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /var/www/html/voxrepublic/app/console(22): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput))
#12 {main}
Comment by Benjamin Eberlei [ 14/Apr/13 ]

The problem is that Doctrine seems to detect that you only have on id field on this entity and then a new function of 2.4 throws this error. I will try to reproduce this with your table. Until then could you show me the var_dump() of the $class variable in Doctrine\ORM\ClassMetadataFactory#completeIdGeneratorMapping()? This would help very much already.

Comment by Maximilian Beck [ 15/Apr/13 ]

I have the same error when using "doctrine:mapping:import"

CREATE  TABLE IF NOT EXISTS `dev_Recipe`.`step` (

  `recipe_id` INT NOT NULL ,

  `step_number` INT NOT NULL ,

  `description` TEXT NULL ,

  `timer` INT NULL ,

  `image` VARCHAR(100) NULL ,

  PRIMARY KEY (`recipe_id`, `step_number`) ,

  INDEX `recipe_id_idx` (`recipe_id` ASC) ,

  INDEX `step_number` (`step_number` ASC) ,

  CONSTRAINT `step_recipe_id`

    FOREIGN KEY (`recipe_id` )

    REFERENCES `dev_Recipe`.`recipe` (`recipe_id` )

    ON DELETE NO ACTION

    ON UPDATE NO ACTION)

ENGINE = InnoDB;
Exception trace:
 () at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\MappingException.php:258
 Doctrine\ORM\Mapping\MappingException::singleIdNotAllowedOnCompositePrimaryKey() at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php:1571
 Doctrine\ORM\Mapping\ClassMetadataInfo->getSingleIdentifierFieldName() at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php:422
 Doctrine\ORM\Mapping\ClassMetadataFactory->completeIdGeneratorMapping() at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php:136
 Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata() at \htdocs\SF2\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php:302
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata() at \htdocs\SF2\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php:212
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor() at \htdocs\SF2\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php:112
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata() at \htdocs\SF2\vendor\doctrine\orm\lib\Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand.php:126
 Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand->execute() at \htdocs\SF2\vendor\doctrine\doctrine-bundle\Doctrine\Bundle\DoctrineBundle\Command\Proxy\ConvertMappingDoctrineCommand.php:59
 Doctrine\Bundle\DoctrineBundle\Command\Proxy\ConvertMappingDoctrineCommand->execute() at \htdocs\SF2\vendor\symfony\symfony\src\Symfony\Component\Console\Command\Command.php:240
 Symfony\Component\Console\Command\Command->run() at \htdocs\SF2\vendor\symfony\symfony\src\Symfony\Component\Console\Application.php:193
 Symfony\Component\Console\Application->doRun() at \htdocs\SF2\vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Console\Application.php:78
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at \htdocs\SF2\vendor\symfony\symfony\src\Symfony\Component\Console\Application.php:106
 Symfony\Component\Console\Application->run() at \htdocs\SF2\app\console:22

"var_dump($class);" returns:

object(Doctrine\ORM\Mapping\ClassMetadata)#470 (36) {
  ["name"]=>
  string(10) "Ingredient"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(10) "Ingredient"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(1) {
    [0]=>
    string(12) "ingredientId"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(4) {
    ["ingredientId"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(12) "ingredientId"
      ["columnName"]=>
      string(13) "ingredient_id"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["name"]=>
    array(6) {
      ["fieldName"]=>
      string(4) "name"
      ["columnName"]=>
      string(4) "name"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(45)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["color"]=>
    array(5) {
      ["fieldName"]=>
      string(5) "color"
      ["columnName"]=>
      string(5) "color"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["img"]=>
    array(6) {
      ["fieldName"]=>
      string(3) "img"
      ["columnName"]=>
      string(3) "img"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(45)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(4) {
    ["ingredient_id"]=>
    string(12) "ingredientId"
    ["name"]=>
    string(4) "name"
    ["color"]=>
    string(5) "color"
    ["img"]=>
    string(3) "img"
  }
  ["columnNames"]=>
  array(4) {
    ["ingredientId"]=>
    string(13) "ingredient_id"
    ["name"]=>
    string(4) "name"
    ["color"]=>
    string(5) "color"
    ["img"]=>
    string(3) "img"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(10) "ingredient"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(1) {
    ["ingredientCategory"]=>
    array(15) {
      ["fieldName"]=>
      string(18) "ingredientCategory"
      ["targetEntity"]=>
      string(18) "IngredientCategory"
      ["mappedBy"]=>
      string(10) "ingredient"
      ["type"]=>
      int(8)
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(false)
      ["sourceEntity"]=>
      string(10) "Ingredient"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(false)
  ["containsForeignIdentifier"]=>
  bool(false)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
object(Doctrine\ORM\Mapping\ClassMetadata)#472 (36) {
  ["name"]=>
  string(18) "IngredientCategory"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(18) "IngredientCategory"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(1) {
    [0]=>
    string(2) "id"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(3) {
    ["id"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(2) "id"
      ["columnName"]=>
      string(2) "id"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["name"]=>
    array(6) {
      ["fieldName"]=>
      string(4) "name"
      ["columnName"]=>
      string(4) "name"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(255)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["description"]=>
    array(4) {
      ["fieldName"]=>
      string(11) "description"
      ["columnName"]=>
      string(11) "description"
      ["type"]=>
      string(4) "text"
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(3) {
    ["id"]=>
    string(2) "id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["columnNames"]=>
  array(3) {
    ["id"]=>
    string(2) "id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(19) "ingredient_category"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(2) {
    ["ingredient"]=>
    array(19) {
      ["fieldName"]=>
      string(10) "ingredient"
      ["targetEntity"]=>
      string(10) "Ingredient"
      ["inversedBy"]=>
      string(18) "ingredientCategory"
      ["joinTable"]=>
      array(3) {
        ["name"]=>
        string(30) "ingredient_category_ingredient"
        ["joinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(22) "ingredient_category_id"
            ["referencedColumnName"]=>
            string(2) "id"
          }
        }
        ["inverseJoinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(13) "ingredient_id"
            ["referencedColumnName"]=>
            string(13) "ingredient_id"
          }
        }
      }
      ["type"]=>
      int(8)
      ["mappedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(18) "IngredientCategory"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["joinTableColumns"]=>
      array(2) {
        [0]=>
        string(22) "ingredient_category_id"
        [1]=>
        string(13) "ingredient_id"
      }
      ["relationToSourceKeyColumns"]=>
      array(1) {
        ["ingredient_category_id"]=>
        string(2) "id"
      }
      ["relationToTargetKeyColumns"]=>
      array(1) {
        ["ingredient_id"]=>
        string(13) "ingredient_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
    ["parent"]=>
    array(19) {
      ["fieldName"]=>
      string(6) "parent"
      ["targetEntity"]=>
      string(18) "IngredientCategory"
      ["joinColumns"]=>
      array(1) {
        [0]=>
        array(2) {
          ["name"]=>
          string(9) "parent_id"
          ["referencedColumnName"]=>
          string(2) "id"
        }
      }
      ["type"]=>
      int(2)
      ["mappedBy"]=>
      NULL
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(18) "IngredientCategory"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["sourceToTargetKeyColumns"]=>
      array(1) {
        ["parent_id"]=>
        string(2) "id"
      }
      ["joinColumnFieldNames"]=>
      array(1) {
        ["parent_id"]=>
        string(9) "parent_id"
      }
      ["targetToSourceKeyColumns"]=>
      array(1) {
        ["id"]=>
        string(9) "parent_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(false)
  ["containsForeignIdentifier"]=>
  bool(false)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
object(Doctrine\ORM\Mapping\ClassMetadata)#474 (36) {
  ["name"]=>
  string(6) "Recipe"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(6) "Recipe"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(1) {
    [0]=>
    string(8) "recipeId"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(3) {
    ["recipeId"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(8) "recipeId"
      ["columnName"]=>
      string(9) "recipe_id"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["name"]=>
    array(6) {
      ["fieldName"]=>
      string(4) "name"
      ["columnName"]=>
      string(4) "name"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(255)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["description"]=>
    array(4) {
      ["fieldName"]=>
      string(11) "description"
      ["columnName"]=>
      string(11) "description"
      ["type"]=>
      string(4) "text"
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(3) {
    ["recipe_id"]=>
    string(8) "recipeId"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["columnNames"]=>
  array(3) {
    ["recipeId"]=>
    string(9) "recipe_id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(6) "recipe"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(2) {
    ["recipeCategory"]=>
    array(15) {
      ["fieldName"]=>
      string(14) "recipeCategory"
      ["targetEntity"]=>
      string(14) "RecipeCategory"
      ["mappedBy"]=>
      string(6) "recipe"
      ["type"]=>
      int(8)
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(false)
      ["sourceEntity"]=>
      string(6) "Recipe"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["orphanRemoval"]=>
      bool(false)
    }
    ["users"]=>
    array(19) {
      ["fieldName"]=>
      string(5) "users"
      ["targetEntity"]=>
      string(5) "Users"
      ["inversedBy"]=>
      string(12) "recipeRecipe"
      ["joinTable"]=>
      array(3) {
        ["name"]=>
        string(13) "users_recipes"
        ["joinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(16) "recipe_recipe_id"
            ["referencedColumnName"]=>
            string(9) "recipe_id"
          }
        }
        ["inverseJoinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(8) "users_id"
            ["referencedColumnName"]=>
            string(2) "id"
          }
        }
      }
      ["type"]=>
      int(8)
      ["mappedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(6) "Recipe"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["joinTableColumns"]=>
      array(2) {
        [0]=>
        string(16) "recipe_recipe_id"
        [1]=>
        string(8) "users_id"
      }
      ["relationToSourceKeyColumns"]=>
      array(1) {
        ["recipe_recipe_id"]=>
        string(9) "recipe_id"
      }
      ["relationToTargetKeyColumns"]=>
      array(1) {
        ["users_id"]=>
        string(2) "id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(false)
  ["containsForeignIdentifier"]=>
  bool(false)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
object(Doctrine\ORM\Mapping\ClassMetadata)#476 (36) {
  ["name"]=>
  string(14) "RecipeCategory"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(14) "RecipeCategory"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(1) {
    [0]=>
    string(2) "id"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(3) {
    ["id"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(2) "id"
      ["columnName"]=>
      string(2) "id"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["name"]=>
    array(6) {
      ["fieldName"]=>
      string(4) "name"
      ["columnName"]=>
      string(4) "name"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(45)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["description"]=>
    array(6) {
      ["fieldName"]=>
      string(11) "description"
      ["columnName"]=>
      string(11) "description"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(45)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(3) {
    ["id"]=>
    string(2) "id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["columnNames"]=>
  array(3) {
    ["id"]=>
    string(2) "id"
    ["name"]=>
    string(4) "name"
    ["description"]=>
    string(11) "description"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(15) "recipe_category"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(2) {
    ["recipe"]=>
    array(19) {
      ["fieldName"]=>
      string(6) "recipe"
      ["targetEntity"]=>
      string(6) "Recipe"
      ["inversedBy"]=>
      string(14) "recipeCategory"
      ["joinTable"]=>
      array(3) {
        ["name"]=>
        string(22) "recipe_category_recipe"
        ["joinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(18) "recipe_category_id"
            ["referencedColumnName"]=>
            string(2) "id"
          }
        }
        ["inverseJoinColumns"]=>
        array(1) {
          [0]=>
          array(2) {
            ["name"]=>
            string(9) "recipe_id"
            ["referencedColumnName"]=>
            string(9) "recipe_id"
          }
        }
      }
      ["type"]=>
      int(8)
      ["mappedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(14) "RecipeCategory"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["joinTableColumns"]=>
      array(2) {
        [0]=>
        string(18) "recipe_category_id"
        [1]=>
        string(9) "recipe_id"
      }
      ["relationToSourceKeyColumns"]=>
      array(1) {
        ["recipe_category_id"]=>
        string(2) "id"
      }
      ["relationToTargetKeyColumns"]=>
      array(1) {
        ["recipe_id"]=>
        string(9) "recipe_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
    ["parent"]=>
    array(19) {
      ["fieldName"]=>
      string(6) "parent"
      ["targetEntity"]=>
      string(14) "RecipeCategory"
      ["joinColumns"]=>
      array(1) {
        [0]=>
        array(2) {
          ["name"]=>
          string(9) "parent_id"
          ["referencedColumnName"]=>
          string(2) "id"
        }
      }
      ["type"]=>
      int(2)
      ["mappedBy"]=>
      NULL
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(14) "RecipeCategory"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["sourceToTargetKeyColumns"]=>
      array(1) {
        ["parent_id"]=>
        string(2) "id"
      }
      ["joinColumnFieldNames"]=>
      array(1) {
        ["parent_id"]=>
        string(9) "parent_id"
      }
      ["targetToSourceKeyColumns"]=>
      array(1) {
        ["id"]=>
        string(9) "parent_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(false)
  ["containsForeignIdentifier"]=>
  bool(false)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
object(Doctrine\ORM\Mapping\ClassMetadata)#478 (36) {
  ["name"]=>
  string(4) "Step"
  ["namespace"]=>
  string(0) ""
  ["rootEntityName"]=>
  string(4) "Step"
  ["customGeneratorDefinition"]=>
  NULL
  ["customRepositoryClassName"]=>
  NULL
  ["isMappedSuperclass"]=>
  bool(false)
  ["parentClasses"]=>
  array(0) {
  }
  ["subClasses"]=>
  array(0) {
  }
  ["namedQueries"]=>
  array(0) {
  }
  ["namedNativeQueries"]=>
  array(0) {
  }
  ["sqlResultSetMappings"]=>
  array(0) {
  }
  ["identifier"]=>
  array(2) {
    [0]=>
    string(10) "stepNumber"
    [1]=>
    string(6) "recipe"
  }
  ["inheritanceType"]=>
  int(1)
  ["generatorType"]=>
  int(1)
  ["fieldMappings"]=>
  array(4) {
    ["stepNumber"]=>
    array(6) {
      ["id"]=>
      bool(true)
      ["fieldName"]=>
      string(10) "stepNumber"
      ["columnName"]=>
      string(11) "step_number"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(false)
    }
    ["description"]=>
    array(4) {
      ["fieldName"]=>
      string(11) "description"
      ["columnName"]=>
      string(11) "description"
      ["type"]=>
      string(4) "text"
      ["nullable"]=>
      bool(true)
    }
    ["timer"]=>
    array(5) {
      ["fieldName"]=>
      string(5) "timer"
      ["columnName"]=>
      string(5) "timer"
      ["type"]=>
      string(7) "integer"
      ["unsigned"]=>
      bool(false)
      ["nullable"]=>
      bool(true)
    }
    ["image"]=>
    array(6) {
      ["fieldName"]=>
      string(5) "image"
      ["columnName"]=>
      string(5) "image"
      ["type"]=>
      string(6) "string"
      ["length"]=>
      int(100)
      ["fixed"]=>
      bool(false)
      ["nullable"]=>
      bool(true)
    }
  }
  ["fieldNames"]=>
  array(4) {
    ["step_number"]=>
    string(10) "stepNumber"
    ["description"]=>
    string(11) "description"
    ["timer"]=>
    string(5) "timer"
    ["image"]=>
    string(5) "image"
  }
  ["columnNames"]=>
  array(4) {
    ["stepNumber"]=>
    string(11) "step_number"
    ["description"]=>
    string(11) "description"
    ["timer"]=>
    string(5) "timer"
    ["image"]=>
    string(5) "image"
  }
  ["discriminatorValue"]=>
  NULL
  ["discriminatorMap"]=>
  array(0) {
  }
  ["discriminatorColumn"]=>
  NULL
  ["table"]=>
  array(1) {
    ["name"]=>
    string(4) "step"
  }
  ["lifecycleCallbacks"]=>
  array(0) {
  }
  ["associationMappings"]=>
  array(1) {
    ["recipe"]=>
    array(20) {
      ["fieldName"]=>
      string(6) "recipe"
      ["targetEntity"]=>
      string(6) "Recipe"
      ["id"]=>
      bool(true)
      ["joinColumns"]=>
      array(1) {
        [0]=>
        array(2) {
          ["name"]=>
          string(9) "recipe_id"
          ["referencedColumnName"]=>
          string(9) "recipe_id"
        }
      }
      ["type"]=>
      int(1)
      ["mappedBy"]=>
      NULL
      ["inversedBy"]=>
      NULL
      ["isOwningSide"]=>
      bool(true)
      ["sourceEntity"]=>
      string(4) "Step"
      ["fetch"]=>
      int(2)
      ["cascade"]=>
      array(0) {
      }
      ["isCascadeRemove"]=>
      bool(false)
      ["isCascadePersist"]=>
      bool(false)
      ["isCascadeRefresh"]=>
      bool(false)
      ["isCascadeMerge"]=>
      bool(false)
      ["isCascadeDetach"]=>
      bool(false)
      ["sourceToTargetKeyColumns"]=>
      array(1) {
        ["recipe_id"]=>
        string(9) "recipe_id"
      }
      ["joinColumnFieldNames"]=>
      array(1) {
        ["recipe_id"]=>
        string(9) "recipe_id"
      }
      ["targetToSourceKeyColumns"]=>
      array(1) {
        ["recipe_id"]=>
        string(9) "recipe_id"
      }
      ["orphanRemoval"]=>
      bool(false)
    }
  }
  ["isIdentifierComposite"]=>
  bool(true)
  ["containsForeignIdentifier"]=>
  bool(true)
  ["idGenerator"]=>
  NULL
  ["sequenceGeneratorDefinition"]=>
  NULL
  ["tableGeneratorDefinition"]=>
  NULL
  ["changeTrackingPolicy"]=>
  int(1)
  ["isVersioned"]=>
  NULL
  ["versionField"]=>
  NULL
  ["reflClass"]=>
  NULL
  ["isReadOnly"]=>
  bool(false)
  ["namingStrategy":protected]=>
  object(Doctrine\ORM\Mapping\DefaultNamingStrategy)#258 (0) {
  }
  ["reflFields"]=>
  array(0) {
  }
  ["_prototype":"Doctrine\ORM\Mapping\ClassMetadataInfo":private]=>
  NULL
}
Comment by Benjamin Eberlei [ 09/May/13 ]

Fixed and merged back to 2.3

Comment by Nicholas Van Dusen [ 29/May/13 ]

I tested this again using 2.3.4 (the version which contains this fix) and it is still occurring. Attempting to import mapping for a table with 2 foreign keys in the primary key results in the error "Database does not have any mapping information." Adding a third column on the primary key "fixes" the issue.

Currently our developers are being asked to add a fake third part to the key to work around the issue, then delete that key once they get into the entity class. This is a bit tedious and I'd love to see a fix!

Comment by Nicholas Van Dusen [ 29/May/13 ]

Issue still present in 2.3.4 and 2.4.0-RC1

Comment by Guillermo [ 11/Jun/13 ]

The database engine I use is PostgreSQL. I'm having problems when mapping entities with composite primary keys in other tables.

CREATE TABLE public.establecimiento
    (
      id_establecimiento integer NOT NULL,
      establecimiento character varying(100) NOT NULL,
      CONSTRAINT pk_establecimiento PRIMARY KEY (id_establecimiento )
    )
    WITH (
      OIDS=FALSE
    );
    CREATE TABLE public.establecimiento_sec
    (
      id_establecimiento_sec integer NOT NULL,
      id_establecimiento integer NOT NULL,
      det_seccion character varying(40) NOT NULL,
      plano character varying(100),
      sector_ingreso character varying(254),
      sponsor_imagen_sec character varying(96000),
      CONSTRAINT pk_establecimientos_sec PRIMARY KEY (id_establecimiento_sec , id_establecimiento ),
      CONSTRAINT fk_establec_reference_establec FOREIGN KEY (id_establecimiento)
          REFERENCES public.establecimiento (id_establecimiento) MATCH SIMPLE
          ON UPDATE RESTRICT ON DELETE RESTRICT
    )
    WITH (
      OIDS=TRUE
    );
    CREATE TABLE public.establecimiento_sec_plano
    (
      id_establecimiento_sec_plano integer NOT NULL,
      id_establecimiento_sec integer NOT NULL,
      id_establecimiento integer NOT NULL,
      det_plano character varying(512),
      cantidad integer NOT NULL,
      precio double precision,
      insert_charge double precision DEFAULT 0,
      descr character varying(254),
      CONSTRAINT pk_establecimiento_sec_plano PRIMARY KEY (id_establecimiento_sec_plano , id_establecimiento_sec , id_establecimiento ),
      CONSTRAINT fk_establecimiento_sec FOREIGN KEY (id_establecimiento, id_establecimiento_sec)
          REFERENCES public.establecimiento_sec (id_establecimiento, id_establecimiento_sec) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE CASCADE
    )
    WITH (
      OIDS=FALSE
    );

Defining the entity establecimientoSecPlano, $establecimientoSec variable containing the keys $establecimiento and $id_establecimiento_sec

//Entity/EstablecimientosSecPlano

/**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Ticketway\PruebaBundle\Entity\EstablecimientosSec")
     * @ORM\JoinColumns(
     *      @ORM\JoinColumn(name="id_establecimiento_sec", referencedColumnName="id_establecimiento_sec"),
     *      @ORM\JoinColumn(name="id_establecimiento", referencedColumnName="id_establecimiento")) 
     */
    private $establecimientoSec;

//Entity/EstablecimientosSec

/**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Ticketway\PruebaBundle\Entity\Establecimientos")
     * @ORM\JoinColumn(name="id_establecimiento", referencedColumnName="id_establecimiento") 
     */
    private $establecimiento;

When executing the command doctrine: mapping: import I get the following error

[Doctrine\ORM\Mapping\MappingException]
It is not possible to map entity 'EstablecimientoSec' with a composite primary key as part of the
primary key of another entity 'EstablecimientoSecPlano#idEstablecimiento'.

Comment by Sam Van der Borght [ 28/Jun/13 ]

We are having the same problem as Guillermo. Any idea on how to fix this issue?
Does anybody know why this problem occurs? I have been looking in the code but havent had much success.

Comment by Diego Antunes [ 01/Jul/13 ]

Doesn't work for me either, composite keys aren't working in 2.3.4

Can we get a fix for this?

Comment by Kamil Adryjanek [ 31/Dec/14 ]

I have similar issue in my current project. Is there any chance to solve this problem in the near future?
Composite primary/foreign keys are important...





[DDC-3473] @Index and @UniqueConstraint do not require the name parameter Created: 31/Dec/14  Updated: 31/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Documentation Priority: Minor
Reporter: Benjamin Morel Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The docs for @Index and @UniqueConstraint both say:

Required attributes:
name: Name of the Index

However, the name parameter does not seem to be required in practice. Omitting it makes Doctrine auto-generate a hash-based name, which is consistent with the indexes generated for foreign keys and is therefore good IMO.

If this is not just a side effect and omitting the name parameter is actually supported, it would be nice to update the docs to reflect this.






[DDC-3469] [GH-1234] added basic test for private embedded field in inheritence Created: 30/Dec/14  Updated: 30/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of Nemo64:

Url: https://github.com/doctrine/doctrine2/pull/1234

Message:

The tried creating a test case for DDC-3467(http://www.doctrine-project.org/jira/browse/DDC-3467). I hope I put everything in the right place as my knowledge of this project is currently limited.






[DDC-3467] Embeddable in inheritance currently must be protected Created: 30/Dec/14  Updated: 30/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.5
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: Marco Pfeiffer Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mapping, orm
Environment:

ubuntu 14.04 PHP 5.5.9-1ubuntu4.5 (cli)



 Description   

I have a setup similar to this one :

Planet.php
/**
 * @ORM\Table()
 * @ORM\Entity(readOnly=true)
 * @ORM\InheritanceType("SINGLE_TABLE")
 **/
abstract class Planet
{
    /* ... */
    /**
     * @var Position
     * @ORM\Embedded(class="Position")
     */
    private $position;
}
Sun.php
/**
 * @ORM\Entity(readOnly=true)
 **/
class Sun extends Planet
{
}

This causes the following error:

[ReflectionException]
Property Sun::$position does not exist

This can easily be fixed by making the embeddable protected, but if I didn't miss anything, a private embed should work too.



 Comments   
Comment by Marco Pivetta [ 30/Dec/14 ]

Can you convert this into a test case? Seems trivial to fix afterwards





[DDC-2838] Leaky abstraction when applying Criteria to hydrated/non-hydrated PersistentCollection Created: 03/Dec/13  Updated: 26/Dec/14

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: brian ridley Assignee: Marco Pivetta
Resolution: Unresolved Votes: 2
Labels: None

Attachments: File DDC2838Test.php    
Issue Links:
Reference
is referenced by DCOM-249 Criteria are unable to locate getters... Open

 Description   

When applying a Criteria to a PersistentCollection that has been hydrated the field names must be camel case, if the collection has not yet been hydrated the field names must be underscore separated.

The github repo linked here contains a simplified testcase for the matrix of hydrated/non-hydrated entities and camel case/underscore separated fields.

https://github.com/ptlis/DoctrineTestcase



 Comments   
Comment by Marco Pivetta [ 18/Aug/14 ]

We can't check out an entire project just to test a bug.

Please write an actual functional test case that can be integrated into the Doctrine ORM test suite.

Comment by brian ridley [ 20/Aug/14 ]

Hi,

i'm happy to do so - i'll take a look at this over the weekend.

Comment by Simon Paridon [ 12/Dec/14 ]

brian ridley: Any progress on this? This is currently an issue for us as well and hope to get fixed. I could look into converting it to a test for integration with the test suite if you don't have the time... but it might take a while since I have no experience with the requirements that should be met. (Plus, I am not sure how tightly coupled it is with your project)

Comment by Simon Paridon [ 17/Dec/14 ]

Hi Marco Pivetta, brian ridley,

I attached a functional Test that integrates with the test suite. Please let me know if I should issue a PR, and I'll do that this evening.

Comment by Florian Preusner [ 26/Dec/14 ]

+1





[DDC-2611] [GH-756] Make yaml/xml configuration for "AttributeOverride" and "AssociationOverride" more discoverable Created: 13/Aug/13  Updated: 26/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Documentation Priority: Trivial
Reporter: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This issue is created automatically through a Github pull request on behalf of peterjmit:

Url: https://github.com/doctrine/doctrine2/pull/756

Message:

I was trying to find out how to configure `AttributeOverride` in yaml for one of my entities and all paths led me to the [Override Field Association Mappings In Subclasses](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/override-field-association-mappings-in-subclasses.html) tutorial.

It was a lot harder to find anything for xml/yaml. This pull request adds a link to the [Overrides section](https://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html#overrides) of the inheritance mapping reference which provides the needed examples.

Alternatively yaml/xml examples could be provided in the tutorial but I am not familiar enough with sphinx/the docs to make those changes



 Comments   
Comment by Doctrine Bot [ 13/Aug/13 ]

A related Github Pull-Request [GH-756] was closed:
https://github.com/doctrine/doctrine2/pull/756

Comment by Doctrine Bot [ 24/Dec/14 ]

A related Github Pull-Request [GH-756] was assigned:
https://github.com/doctrine/dbal/pull/756

Comment by Doctrine Bot [ 26/Dec/14 ]

A related Github Pull-Request [GH-756] was closed:
https://github.com/doctrine/dbal/pull/756





[DDC-3463] Generated enitities have singular variable names for many to many relationships Created: 25/Dec/14  Updated: 25/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: John J Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Running doctrine:generate:entities from the command line gives entities that have instance variables arrays, but their names are singular. For example if there are many "tools" associated with a "toolbox" via a many to one or many to many realationship, the toolbox class should have an array variable named "tools". It has an array but the name of it is "tool" instead of "tools". The name of the variable should be singular for one to one relationships and plural for whenever its an array






[DDC-3460] SchemaTool create unnecessry work by trying to set foreign keys on MyISAM tables Created: 20/Dec/14  Updated: 20/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: flack Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When I run SchemaTool::getSchemaFromMetadata, it always adds foreign keys constraints for all association fields (in SchemaTool::gatherRelationJoinColumns). Since I've set the table's engine option to 'MyISAM', this is quite pointless, since they won't get created anyways.

When I run SchemaManager::createSchema, it does not detect any foreign keys, so the SchemaDiff from Comparator will contain a large number of (pointless) ADD CONSTRAINT FK_xxx FOREIGN KEY commands.

For the moment, I work around this by removing them in a ToolEvents::postGenerateSchemaTable listener, but shouldn't SchemaTool be able to detect this situation itself?






[DDC-3459] double inversed-by leads to incomprehensible error message Created: 20/Dec/14  Updated: 20/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Tom Vogt Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When mapping a many-to-one relationship (in XML format), I made the mistake of having both sides be inversed-by (instead of one using mapped-by). This resulted in the following error message on doctrine:schema:update

Doctrine\ORM\ORMException: This behaviour is (currently) not supported by Doctrine 2 (uncaught exception) at /Volumes/User Data/Users/Tom/Sites/BM2/vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php line 217 while running console command `doctrine:schema:update`

This message could be more helpful. It doesn't tell me where the error is nor what the error is.






[DDC-3203] "Orphan Removal" for ManyToMany and "Cascade remove" doesn't trigger "preRemove" callback on related entity Created: 01/Jul/14  Updated: 19/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Tadej Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Latest ZendFramework2, latest ZF2 DoctrineModule and latest ZF2 DoctrineORMModule



 Description   

I'm not sure if it's me, but I couldn't get "preRemove" callback/event working when "remove" action is triggered from related entity, but it works where the entity itself (the one with "preRemove" event) is removed directly.

According to documentation:
"If an association is marked as CASCADE=REMOVE Doctrine 2 will fetch this association. If its a Single association it will pass this entity to ´EntityManager#remove()`"....and similar for multiple entities.
DOC: http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html?highlight=working-with-objects%20removing-entities#removing-entities

"preRemove event is called on every entity when its passed to the EntityManager#remove()"
DOC: http://docs.doctrine-project.org/en/latest/reference/events.html#preremove

So according to documentation "preRemove" should get triggered on "cascade remove", but it doesn't get in my case. Is this normal behavior or a bug?

I'm not sure if it the problem might be in any of ZF2 modules, but I've decided to post the issue here, since I'm referring to documentation of this project.

Beside that I've also noticed that "orphan removal" doesn't work on ManyToMany, although documentation says that it's supported (on IRC they've said that it may be a bug in documentation, that it is not really yet supported...they found no code changes when documentation was changed).
DOC:
http://docs.doctrine-project.org/en/latest/reference/working-with-associations.html#orphan-removal



 Comments   
Comment by Oliver Hoff [ 19/Dec/14 ]

Orphan removal can not be supported for Many-To-Many relations, because the feature makes the assumption that the related entity is "privately owned" by the entity defining the orphan removal feature. In a Many-To-Many relation a related entity can be related to multiple entities and therefore is not privately owned by the relation defining entity.





[DDC-3450] Embeddables containing only nested embeddables are not hydrated properly Created: 16/Dec/14  Updated: 16/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.5
Fix Version/s: None

Type: Bug Priority: Major
Reporter: James Moss Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I have the following object mapping:

Location (entity)

  • name <string>
  • bounds <Bounds>

Bounds (embeddable)

  • northeast <Coords>
  • southwest <Coords>

Coords (embeddable)

  • latitude <float>
  • longitude <float>

This setup works fine when persisting entities, the database schema is correct, etc. but when I fetch my `Location` entity afterwards the `bounds` property is wrong. It looks something like this. Calling `getBounds()` on `Location` returns something like:

Coords

  • latitude <float>
  • longitude <float>
  • northeast <Coords>
  • southwest <Coords>

As if the `Coords` embeddable has been transposed with the `Bounds` embeddable.

If I add another property to `Bounds` that isn't an embeddable (say a string) then it's hydrated correctly.



 Comments   
Comment by Marco Pivetta [ 16/Dec/14 ]

James Moss could you come up with a small test case in https://github.com/doctrine/doctrine2/tree/v2.4.7/tests/Doctrine/Tests/ORM/Functional/Ticket ?





[DDC-3449] Single scalar Result and Hidden field Created: 15/Dec/14  Updated: 15/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.6
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Thomas Gallice Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I have try to get a single scalar result but my query contains a HIDDEN field. The result is the `NonUniqueResultException` exception.






[DDC-3448] @OrderBy on eager @OneToMany does not work Created: 13/Dec/14  Updated: 13/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Oliver Hoff Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

generated code when eagerly fetching:

SELECT 
  t0.id AS id_8,
  t19.category_id AS category_id_23 
FROM 
  category t0 
  LEFT JOIN attribute_category t19 ON t19.category_id = t0.id 
WHERE 
  t0.id = ?

when fetching lazy the collection query has the ORDER BY clause






[DDC-3284] Yaml mapping. Comment on table and realtion Created: 29/Aug/14  Updated: 12/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: Documentation, Mapping Drivers, ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Documentation Priority: Major
Reporter: Vladimir Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Windows, XAMPP, PHP5.3, ZF2, Doctrine-ORM



 Description   

Is there any way to comment my tables and table relations with yml schema?
I can comment plain field like this

        prediction:
            type: text
            nullable: true
            length: null
            fixed: false
            options:                
                comment: 'program prediction'

But for relation:

        project:
            targetEntity: File\Entity\File
            cascade: {  }
            mappedBy: null
            inversedBy: null
            joinColumns:
                project:
                    referencedColumnName: id
            orphanRemoval: false
            options:                
                comment: 'File with project data'

Or for whole table:

Program\Entity\Program:
    type: entity
    table: program
    options:
        comment: 'State program table'

It doesn't work at all. When I perform migrations those comments are totally ignored. And I can't find any documentation for yml mapping table commenting



 Comments   
Comment by Steve Müller [ 29/Aug/14 ]

Commenting tables is a vendor specific feature and therefore not all database vendors support it. I think currently it is only possible to comment tables via mapping for MySQL. The mapping you provided for commenting tables should work however. See here: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php#L247-L249
I'm not quite sure what you mean by commenting relations. Where would you expect Doctrine to add a comment to?

Comment by Vladimir [ 29/Aug/14 ]

I mean commenting a column that is a foreign key. Like 'project' column above that is a link to Files table and entity.

Comment by Steve Müller [ 01/Sep/14 ]

Unfortunately commenting columns part of an association mapping is not possible in ORM at the moment.

Comment by Martijn Zijlstra [ 09/Dec/14 ]

I tried doing this with annotations by adding a column annotation to the relation, but this effectively removed the relation alltogether. So no workaround yet.

Comment by Steve Müller [ 12/Dec/14 ]

Commenting foreign key columns is simply not supported yet via ORM mapping.





[DDC-3445] ERROR GENERATED VALUE (UUID) Created: 10/Dec/14  Updated: 11/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.3
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: MUHAMAD SURYA IKSANUDIN Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm, postgresql


 Description   

UUID is not working (missing ID and need to set manually)

/**
 * @ORM\Entity
 * @ORM\Table(name = "utl_role")
 */
class Role implements EntityInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(name = "id", type = "guid")
     * @ORM\GeneratedValue(strategy = "UUID")
     **/
    protected $id;

===============================

i need to pass the id manually

$role->setId((new UuidGenerator())->generate($this->em, $role)); 

because the id is not set and error when i try to persist.

This error is arrive when i try to persist an entity i loop

================================

I use postgresql 9.3



 Comments   
Comment by Marco Pivetta [ 11/Dec/14 ]

Can you check this also against master (2.5-dev)?

Comment by MUHAMAD SURYA IKSANUDIN [ 11/Dec/14 ]

i think it same because the uuid generator is same

https://github.com/doctrine/doctrine2/blob/master/lib%2FDoctrine%2FORM%2FId%2FUuidGenerator.php#L42

in that code, i see the uuid is generated from database provider/platform, i suggest to use code base generator like

https://github.com/ramsey/uuid/blob/master/src%2FUuid.php

it just my suggestion

thanks





[DDC-3447] Identifier Generation Strategy "UUID" is missing Created: 10/Dec/14  Updated: 10/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Documentation Priority: Minor
Reporter: David Fuhr Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: GeneratedValue


 Description   

The listing of the Identifier Generation Strategies as http://doctrine-orm.readthedocs.org/en/latest/reference/basic-mapping.html#identifier-generation-strategies misses the UUID.

The annotation reference contains the value for UUID http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-generatedvalue

So it should be added at the "Identifier Generation Strategies"






[DDC-3424] Class Table Inheritance - wrong table order on insert with more than one level of inheritance Created: 02/Dec/14  Updated: 04/Dec/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.3
Fix Version/s: 2.2.3
Security Level: All

Type: Bug Priority: Major
Reporter: mohammed Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: ORM
Environment:

Mysql



 Description   

when i use class table inheritance with multiple levels in doctrine :
Account<=User<=Dealer
(Dealer inherits from User, User from Account)
Account has the discriminator column and mapping.
when i persist a new Dealer entity I get a foreign key error because there is no row in the User table.
So the order in which the insert statements are executed:
1) Insert into Account
2) Insert into Dealer (which causes the error)
3) insert into User
Can someone help me thanks in advance.



 Comments   
Comment by Marco Pivetta [ 02/Dec/14 ]

Is this also valid for 2.4.x and master? 2.3.3 is a very old version.

Additionally, could you come up with a small reproduction test case? You can check the ones at https://github.com/doctrine/doctrine2/tree/v2.4.6/tests/Doctrine/Tests/ORM/Functional/Ticket for reference

Comment by mohammed [ 03/Dec/14 ]

This is also valid for 2.4.x and master
this is the test case https://github.com/rogerghost/doctrine2/blob/patch-1/tests/Doctrine/Tests/ORM/Persisters/DDC3424Test.php





[DDC-3181] Class Table Inheritance - wrong table order on insert with more than one level of inheritance Created: 20/Jun/14  Updated: 02/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: M. de Lange Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: orm
Environment:

oracle



 Description   

note: this issue seems the same as DDC-732

When using class table inheritance with multiple levels i.e.:
Object -> SolidObject -> Building -> House
(House inherits from Building, Building from SolidObject, SolidObject from Object)

Object has the discriminator column and mapping. When persisting a new House entity I get a foreign key error because there is no row in the Building table.

I searched in the Code and found the problem. In the class "Doctrine\ORM\Persisters\JoinedSubclassPersister" in function "executeInserts()" around line 146 the array $subTableStmts is first declared and then filled with insert statements. The statement of the House-table is first added, and then the parent-tables (except the root-table "Object", since that one is executed first).

So the order in which the insert statements are executed is:
1 Insert into Object ...
2 Insert into House ... (which causes the error)
3 insert into Building ...
4 Insert into SolidObject

I edited the source to insert into the parent-tables (first SolidObject, then Building) before inserting into the table that belongs to the class that is persisted (House). And this works



 Comments   
Comment by mohammed [ 26/Nov/14 ]

hello, can you please send me the modified lines or just share with me the whole method executeInserts.
thanks in advance





[DDC-1825] generate entities with traits Created: 18/May/12  Updated: 01/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2.2
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Matthias Breddin Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 5
Labels: None
Environment:

php 5.4.3, symfony2.1-dev
php 5.5.12, symfony 2.5



 Description   

When a trait with included setters and getters is used and generate entities is called, doctrine add another set of getters and setters to the "main" entity where the trait is used.



 Comments   
Comment by Martin Aarhof [ 01/May/14 ]
/**
 * @ORM\Entity
 */
class Product {
    use Traits\Created;

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

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * Set name
     *
     * @param string $name
     * @return Attribute
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

}
Trait Created {
    /**
     * @var \DateTime $created
     *
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(type="datetime")
     */
    private $created;

    /**
     * @return \DateTime
     */
    public function getCreated()
    {
        return $this->created;
    }
}

Now when I run php app/console doctrine:generate:entities it copies everything from the trait and into the entity, so the entity now looks like

/**
 * @ORM\Entity
 */
class Product {
    use Traits\Created;

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

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * Set name
     *
     * @param string $name
     * @return Attribute
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @var \DateTime $created
     *
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(type="datetime")
     */
    private $created;

    /**
     * @return \DateTime
     */
    public function getCreated()
    {
        return $this->created;
    }

}

And ofcourse invalidates the entity because it now has two methods of the getCreated and two of private $created

Comment by Wilgert Velinga [ 01/Dec/14 ]

Unfortunately I am also suffering from this bug. Is there anything I can do to help resolve it?





[DDC-3423] Column Ordering when creating tables using doctrine:schema:update Created: 01/Dec/14  Updated: 01/Dec/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Raja Venkataraman Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When you have a Base class (annotated with @MappedSuperClass) having some columns, say, createdById, createdDateTime and child entities deriving from the BaseClass, the ordering of the SQL when running doctrine:schema:update looks like

createdById
createdDateTime
id
field1
field2

i.e. the columns of the Base class come up first and then that of the children. It looks odd when you write a SQL to insert into these tables because the default ordering is not what you expect (Which would be derived class columns first and then base class).

I looked into ClassMetadataFactory that adds the fields to the classmetadata and figured if we could move the following
$this->addInheritedFields($class, $parent);
$this->addInheritedRelations($class, $parent);

to after the point where the local fields are added to the classmetadata, this problem is solved.

It might be even better if we have an annotation to specify the Ordering of columns but nevertheless this will help in cases where the base class columns appear after the derived class columns.

Note: Did look into columnDefinition annotation to specify a "AFTER <column>", but that cannot be used during CREATE TABLE, only for ALTER TABLE and that too, its mysql specific.






[DDC-3230] Bug in clear cache Created: 25/Jul/14  Updated: 30/Nov/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 64bits
PHP 5.5.4 32 bits
pdo_sql_srv 3.0.2 for php 5.5 32 bits
symfony 2.5
gedmo deletable @ dev-master
Redis 2.8.12
PHPRedis php_redis-2.2.5-5.5-nts-vc11-x86
IIS 7.5



 Description   

1. Redis is used for cache/meta/result caching.
2. Entity has property $deleted with gedmo deletable on it.
3. Removing property $deleted (and all related annotations)
4. Symfony commands:

php app/console doctrine:cache:clear-metadata
php app/console doctrine:cache:clear-query
php app/console doctrine:cache:clear-result
php app/console cache:clear --env=prod --no-debug <-- error on this command

5. [ReflectionException]
Property Entity::$deleted does not exist

Trace:

#0 \vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php(989)
#1 \vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php(571)
#2 \vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(210) <-- CacheRedis driver called here
#3 \vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(114)
#4 \vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\CacheWarmer\ProxyCacheWarmer.php(69)
#5 \vendor\symfony\symfony\src\Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate.php(48)
#6 \app\bootstrap.php.cache(2513)
#7 \app\bootstrap.php.cache(2284)
#8 \vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand.php(128)
#9 \vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand.php(90)
#10 \vendor\symfony\symfony\src\Symfony\Component\Console\Command\Command.php(252)
#11 \vendor\symfony\symfony\src\Symfony\Component\Console\Application.php(894)
#12 \vendor\symfony\symfony\src\Symfony\Component\Console\Application.php(193)
#13 \vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Console\Application.php(96)
#14 \vendor\symfony\symfony\src\Symfony\Component\Console\Application.php(124)
#15 \app\console(27)

Why do i think this is a Doctrine bug and not a Symfony bug? Because

php app/console doctrine:cache:clear-metadata
php app/console doctrine:cache:clear-query
php app/console doctrine:cache:clear-result

have been called successfully so RedisCache should not return cache with $this->fieldMappings containing key "deleted"



 Comments   
Comment by Erik Verheij [ 30/Nov/14 ]

As a workaround I figured out that when you add the --flush flag it works as expected. You can read some documentation about what's going in this file; https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php#L44.

orm:clear-cache:metadata --flush





[DDC-3273] EntityGenerator writes @ORM\Table annotation for mapped superclass Created: 26/Aug/14  Updated: 27/Nov/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.4.4, 2.4.5, 2.4.6
Fix Version/s: None
Security Level: All

Type: Bug Priority: Minor
Reporter: Jakab Adam Balazs Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: generation, orm, tools
Environment:

not relevant


Issue Links:
Reference
is referenced by DDC-3418 Indexes not inherited from mapped sup... Resolved

 Description   

file /doctrine/orm/lib/Doctrine/ORM/Tools/EntityGenerator.php method: generateTableAnnotation returns @ORM\Table annotation even for mapped superclass entities. Since classes with annotation @ORM\MappedSuperclass are only to be extended and will NOT have a database table associated to them they should not have '@ORM\Table' annotation at all.
It would be enough to wrap the method body with `if ($metadata->isMappedSuperclass)

{ ... }

`.






[DDC-3413] Types are always ignored when performing a one to many statement Created: 26/Nov/14  Updated: 27/Nov/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Edouard COLE Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: persister


 Description   

BasicEntityPersister#getOneToManyStatement() is building an array named $criteria. This array is built this way:

$criteria[$tableAlias . "." . $targetKeyColumn] = ...;

This means this array is indexed by keys looking like that:

t0.fieldName

But the function BasicEntityPersister#expandParameters() is used in this function, and this function is NOT able to handle SQL field name as keys, but PHP attributes, because it uses BasicEntityPersister#getType() which is doing this:

case (isset($this->class->fieldMappings[$field])):
case (isset($this->class->associationMappings[$field])):

I think the $criteria array should be used to call BasicEntityPersister#getSelectSQL(), but another array should be passed to expandParameters. Here is a potential fix:

$cleanCriteria[$owningAssoc['fieldName']] = $criteria[$tableAlias . "." . $targetKeyColumn] = ...;

And $cleanCriteria should be passed to expandParameters.



 Comments   
Comment by Marco Pivetta [ 27/Nov/14 ]

Edouard COLE I suggest you to open a pull request with a failing test case, otherwise this issue is hard to follow/understand.





[DDC-3410] Allow Query Builder to specify the joins of Join Inheritance entities Created: 25/Nov/14  Updated: 25/Nov/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Dave Newson Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Possibly a duplicate of DDC-16 in essence; resolving this would probably resolve that issue.

Summary
When you SELECT an entity which is a superclass using Joined Inheritance, Doctrine automatically adds it's own JOINs of the superclass or subclass tables.
These automatic JOINs that are introduced can't be used in DQL/builder, so you can't do anything with them (further joins on their associations for eager loading, WHERE queries, etc).
Allow me to specify my own Joins between the superclass and subclass so I can perform further queries deeper in the associations.

Main culprit:
https://github.com/doctrine/doctrine2/blob/2.4/lib/Doctrine/ORM/Query/SqlWalker.php#L341

Long version
Superclass "Activity" uses the Joined inheritance type with a discriminator column. There are various activities such as ActivityDocument, ActivityTask, etc.
These sub-class activities have associations to other entities; ActivityDocument associates to a Document entity, and Document then associates to User.

For the query, I want to fetch all Activity where the Activities document/task is associated to a given user. If I wanted to do this in raw SQL it would look something like this:

SELECT a.*, ad.*, d.*, at.*, t.*
FROM Activity a
LEFT JOIN ActivityDocument ad ON ad.id = a.id
LEFT JOIN Document d ON d.id = ad.document_id
LEFT JOIN ActivityTask at ON at.id = a.id
LEFT JOIN Task t ON t.id = at.task_id
WHERE
t.user_id = 1 OR d.user_id = 1

Doctrine supports the joined inheritance type, so I want it to fetch the subclasses and also eagerly load the downstream Document or Task entity that's associated with them, and be able to execute clauses on the data.

I can only get half way there:

$builder
    ->select('a')
    ->from('Activity', 'a')
    ->leftJoin('ActivityDocument', 'ad', Query\Expr\Join::WITH, 'a.id = ad.id')
    ->leftJoin('ad.document', 'ad_d')
    ->orWhere('ad_d.user = :user')
    ->leftJoin('ActivityTask', 'at', Query\Expr\Join::WITH, 'a.id = at.id')
    ->leftJoin('at.task', 'at_t')
    ->orWhere('at_t.user = :user')
    ->setParameter('user', $user);

In the above I've fudged the joined inheritance association using ->leftJoin() in order to execute the deep WHERE portion, however because we're doing our own join between two entities, the association between Activity and ActivityDocument is lost.

The entities returned by this query are instances of ActivityDocument and ActivityTask; the hydrated subclasses are returned when we SELECT from Activity, and ActivityDocument and ActivityTask are LEFT JOINed automatically by Doctrine because the Activity entity is recognised as using Joined Inheritance, but there's no way to latch onto these generated LEFT JOINs.
https://github.com/doctrine/doctrine2/blob/2.4/lib/Doctrine/ORM/Query/SqlWalker.php#L376

Note that adding "ad", "at" or "at_d" or "at_t" to the select does not solve this.

A workaround for this specific scenario is this:

$builder->select('ad', 'at', 'ad_d', 'at_t')

This fetch ActivityDocument and ActivityTask specifically, plus their associations. Unfortunately because it is across multiple to-level entities, it causes null rows to be returned in the result set.

Effectively this goes the other way, and adds joins from ActivityDocument to Activity in order to provide the correct hydration of ActivityDocument.
https://github.com/doctrine/doctrine2/blob/2.4/lib/Doctrine/ORM/Query/SqlWalker.php#L348

Note that you still cannot use an alias for Activity because the builder was not the one to specify that relation.

What I want to be able to do
Allow me to define the join across the Join Inheritance entities, so I can use the alias for the superclass/subclass in the query builder!

Rather than DDC-16's idea of "casting" to a class, just let me define the join myself. Obviously this is more a "joined class" than a "joined field" , so extra notation may be required.
A painfully ugly example of this syntax could be something like:

$builder->join('Activity->ActivityDocument', 'ad')

This could then establish the Join as some form of JoinAssociation rather than a RangeVariableDeclaration.

The bigger problem is that SqlWalker::_generateClassTableInheritanceJoins doesn't have scope over any of the joins in the query, and thus can't inspect any relations that have been established in the query builder, and use those instead of generating its own.

Unfortunately I don't know the internals of Doctrine to be of any more use.

Why
Joined Inheritance is a powerful feature, but without being able to use associations across the superclass and subclass it actually creates an annoying dead-end in queries.

There is no good workaround for this issue. If you fetch a Join Inheritance entity you can only examine one side of the inheritance without performing another query.






[DDC-3407] add possibility to prevent some entitiy methods from being proxied Created: 21/Nov/14  Updated: 21/Nov/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Trivial
Reporter: Oliver Hoff Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This is for optimization of lazy loading, when using entity methods that operate only on identifier values.

This issue is partially addressed via:
https://github.com/doctrine/doctrine2/commit/ba38f3e1e9d725224998af9fce42186b5ccb9641

But it makes assumptions about a certain code style, that is for an "id" identifier property the getter is named "getId". but some code styles prefer "getID".

It would be nice to have an annotation like @ORM\SkipProxy (or equivalents for xml/yaml) to mark a method that should not be proxied.



 Comments   
Comment by Marco Pivetta [ 21/Nov/14 ]

I wouldn't implement it that way. I'm actually building something (non-trivial) at https://github.com/Ocramius/ProxyManager/pull/192 and https://github.com/Ocramius/ProxyManager/issues/159, but it will take some time to get there, and also to get doctrine to use that component to generate proxy classes.





[DDC-3400] Wrong result using php-cli Created: 19/Nov/14  Updated: 20/Nov/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.6
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Damir Abdijevic Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: cache, cli, dql, environment, orm
Environment:

Windows 7, Debian GNU/Linux 7 PHP 5.5.15



 Description   

Same query produces different results. With apache module everything works like expected. With php-cli the join condition to i18n table is ignored and calling getCountries() returns all and not only that entity that is matched by join condition.

        $qb = $this->_em->createQueryBuilder()
                        ->select('t', 'i18n')
                        ->from($this->_entityName, 't')
                        ->innerJoin('t.countries', 'i18n')
                        ->where('i18n.locale = :localeId')
                        ->setParameter('localeId', $localeId);

Country Entity:

namespace MyApp\Model\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Country entity
 *
 * @ORM\Entity(repositoryClass="MyApp\Model\Repository\Country")
 * @ORM\Table(name="country")
 *
 */
class Country
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer", name="id")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     * @ORM\Column(type="string", name="name", length=32, unique=true)
     */
    protected $name;

    /**
     * @var int
     * @ORM\Column(type="integer", name="sort", unique=true)
     */
    protected $sort;

    /**
     * @var ArrayCollection
     * @ORM\OneToMany(targetEntity="ProductDescription\Model\Entity\CountryI18n", mappedBy="country", cascade={"all"})
     */
    protected $countries;


    /**
     * Constructor
     *
     * @return Country
     */
    public function __construct()
    {
        $this->countries = new ArrayCollection();
    }

    /**
     * Getter for $this->id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Setter for $this->id
     *
     * @param int $id entity id
     *
     * @return void
     */
    public function setId($id)
    {
        $this->id = (int) $id;
    }

    /**
     * Getter for $this->sort
     *
     * @return int
     */
    public function getSort()
    {
        return $this->sort;
    }

    /**
     * Setter for $this->sort
     *
     * @param int $sort sort order
     *
     * @return void
     */
    public function setSort($sort)
    {
        $this->sort = (int) $sort;
    }

    /**
     * Getter for $this->name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Setter for $this->name
     *
     * @param string $name language name in german
     *
     * @return void
     */
    public function setName($name)
    {
        $this->name = (string) $name;
    }

   /**
    * Get collection from i18n table
    *
    * @return ArrayCollection
    */
    public function getCountries()
    {
        return $this->countries;
    }

    /**
     * Proxy method. So we have working with all entities same method
     * to getting i18n data.
     *
     * @return ArrayCollection
     */
    public function getI18n()
    {
        return $this->getCountries();
    }

CountryI18nEntity:

namespace MyApp\Model\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * CountryI18n entity
 *
 * @ORM\Entity
 * @ORM\Table(name="country_i18n", uniqueConstraints={@ORM\UniqueConstraint(name="idx_UNIQUE_country_id_locale_id", columns={"country_id", "locale_id"})})
 */
class CountryI18n
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer", name="id")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="ProductDescription\Model\Entity\Country", inversedBy="countries")
     * @ORM\JoinColumn(name="country_id", referencedColumnName="id")
     */
    protected $country;

    /**
     * @ORM\ManyToOne(targetEntity="ProductDescription\Model\Entity\Language", inversedBy="countries")
     * @ORM\JoinColumn(name="locale_id", referencedColumnName="id")
     */
    protected $locale;

    /**
     * @var string
     * @ORM\Column(type="string", name="name", length=255)
     */
    protected $name;


    /**
     * Getter for $this->id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Setter for $this->id
     *
     * @param int $id id of row primary key
     *
     * @return void
     */
    public function setId($id)
    {
        $this->id = (int) $id;
    }

    /**
     * Getter for $this->country
     *
     * @return Country
     */
    public function getCountry()
    {
        return $this->country;
    }

    /**
     * Setter for $this->country
     *
     * @param Country $country country entity to set
     *
     * @return void
     */
    public function setCountry(Country $country)
    {
        $this->country = $country;
    }

    /**
     * Getter for $this->locale
     *
     * @return Language
     */
    public function getLocale()
    {
        return $this->locale;
    }

    /**
     * Setter for $this->locale
     *
     * @param Language $locale language entity to set as locale
     *
     * @return void
     */
    public function setLocale(Language $locale)
    {
        $this->locale = $locale;
    }

    /**
     * Getter for $this->name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Setter for $this->name
     *
     * @param string $name translation name
     *
     * @return void
     */
    public function setName($name)
    {
        $this->name = (string) $name;
    }

}


 Comments   
Comment by Marco Pivetta [ 19/Nov/14 ]

Looks like a caching issue. The amount of information provided is insufficient as it is. I'd suggest verifying if the generated SQL is the same, and checking that all caches were cleared both in CLI and in WEB sapis.

Comment by Damir Abdijevic [ 20/Nov/14 ]

O.k. here some further information.

No caching like Xcache or APC is enabled. PHP 5.5 integrated opcache ist not enabled. All Doctrine caches are set to Array. The sql queries are in both cases exactly the same:

sql
SELECT c0_.id AS id0, c0_.name AS name1, c0_.sort AS sort2, c1_.id AS id3, c1_.name AS name4, c1_.country_id AS country_id5, c1_.locale_id AS locale_id6 FROM country c0_ INNER JOIN country_i18n c1_ ON c0_.id = c1_.country_id WHERE c1_.locale_id = ?

/* locale_id = 2 */

The sql result is correct

Running the console script a ZF2 Initializer runs before that performs this query builder query:

QueryBuilder

$qb = $this->_em->createQueryBuilder()
                            ->select('t', 'i18n', 'l')
                            ->from($this->_entityName, 't')
                            ->innerJoin('t.countries', 'i18n')
                            ->innerJoin('i18n.locale', 'l');

That results in following SQL:

sql
SELECT c0_.id AS id0, c0_.name AS name1, c0_.sort AS sort2, c1_.id AS id3, c1_.name AS name4, l2_.id AS id5, l2_.name AS name6, l2_.full_name AS full_name7, l2_.locale AS locale8, c1_.country_id AS country_id9, c1_.locale_id AS locale_id10, l2_.country_id AS country_id11 FROM country c0_ INNER JOIN country_i18n c1_ ON c0_.id = c1_.country_id INNER JOIN language l2_ ON c1_.locale_id = l2_.id
Comment by Marco Pivetta [ 20/Nov/14 ]

What happens if you run those SQL statements via CLI (dbal:run-sql) or WEB? Same results?

Comment by Damir Abdijevic [ 20/Nov/14 ]

The sql result is correct. Can I attach it to the ticket? I have exported it to csv.

Comment by Marco Pivetta [ 20/Nov/14 ]

If the same results are produced on CLI and WEB APIs then I suggest trying to insulate the issue in a functional test to be run in both context. You probably have a different ORM bootstrap for CLI and WEB.

Attaching a CSV for same results makes no real difference here.

Comment by Damir Abdijevic [ 20/Nov/14 ]

No, I didn't want to attach two times the same result. Wanted to attach it one time to show that those entitites that are wrong in the result doesn't appear in the sql result at all. I don't have different bootstraps. After a few short tests I think it is an error in th ArrayCache mechanism. The difference was that using Apache one initializer was not called. Calling this initializer in both cases leads now to wrong results in CLI and WEB API.

When the second query is not executed everything is fine. But when the second longer query runs and selects all i18n entities and after it the first query runs then the issue appears.





[DDC-3391] RFC Allow adding extra metadata attributes Created: 13/Nov/14  Updated: 19/Nov/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Gonzalo Vilaseca Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: drivers, metadata


 Description   

What I'd like to propose is a way of having custom metadata in ClassMetadata.

So the current problem is this: I want to add custom tags to doctrine metadata files, and then get this tags on a loadClassMetadata listener in order to modify the mapping.
Currently the only workaround is parsing this custom tags in the loadClassMetadata listener, going through all the files again.

I was thinking of having a new 'extra' array field in ClassMetadata, every time a driver parses a configuration, throw a new event with the read configuration (being xml, yaml...etc.). A custom listener will parse it looking for the custom tags and return an array that will be added to the 'extra' array field in ClassMetadata.

Then, on the loadClassMetadata listener we retrieve this 'extra' configuration information, and modify the mapping as we want.

Does this make sense?



 Comments   
Comment by Gonzalo Vilaseca [ 14/Nov/14 ]

Ideally instead of the 'extra' array field, it would be nice to easily extend Metadata class so that the new values are filled in the new extended Metadata class.

Comment by Christophe Coevoet [ 14/Nov/14 ]

This would be even worse. If the recommended way for extensions is to extend the Doctrine Metadata object to add their field, it means you can only use 1 extension at a time (because you cannot use the extended class of both extensions at the same time for the same object).
This is why it is much better for other libraries to store their own metadata in their own object instead of trying to put it inside the Doctrine ones.

I'm not even sure putting custom tags inside the Doctrine mapping file is the best solution. It may be better to use a separate metadata file for the mapping of the other library (just like you use a different mapping file for the Symfony validation mapping even if it applies to the same class than the Doctrine mapping for instance)

Comment by Gonzalo Vilaseca [ 14/Nov/14 ]

You're right regarding the metadata.

As for the separate files, validation in Symfony is not doctrine specific, that's why it's in a separate file. If you have a look at some doctrine extensions like ``Prezent translable`` or ``Doctrine2 behavioral extensions``, the natural location for the custom tags are the Doctrine mapping files as they are specific to doctrine, by looking at just one file you see the whole picture.

Yes, you could have your own mapping files, but then you would need to do some Symfony magic to be able to load them, and this is what would be nice to avoid.

I think of it as a way to easily extend doctrine mapping capabilities, in a 'plugin' way.

I'm currently working on a i18n bundle for Symfony, the tags I add in doctrine mapping files create associations between entities and their translations: I've had to create quite a few compiler passes for my current project to work as desired, and I see no way of abstracting this in a general way, it will need to be application specific. If I could hook into the Doctrine workflow and get those tags to populate my metadata class, that would be great, simple and reusable.

Comment by Gonzalo Vilaseca [ 19/Nov/14 ]

I've come out with another use case:
I need some custom metadata when the repository is instantiated, AFAIK there is no way of doing this right now, or is there?

Comment by Marco Pivetta [ 19/Nov/14 ]

You'd use a different metadata factory for that, specific to your use-case.
Mixing ORM mappings with the rest will just cause more coupling between the ORM and the userland use-case.





[DDC-3399] indexBy expects db field names insteadof model property names Created: 19/Nov/14  Updated: 19/Nov/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Documentation Priority: Major
Reporter: Oliver Hoff Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The following example does work:

Unable to find source-code formatter for language: php. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
/**
 * @ORM\Entity
 */
class Order {

	use IDTrait;

	/**
	 * @ORM\OneToMany(
	 * 		targetEntity="OrderCategory",
	 * 		mappedBy="order",
	 * 		indexBy="my_category_id",
	 * 		fetch="EAGER",
	 * 		cascade={"all"},
	 * 		orphanRemoval=true
	 * )
	 * @var Collection
	 */
	private $categories;

}

/**
 * @ORM\Entity
 */
class OrderCategory {

	/**
	 * @ORM\ManyToOne(targetEntity="Order", inversedBy="categories")
	 * @ORM\JoinColumn(name="order_id", referencedColumnName="id", onDelete="CASCADE")
	 * @ORM\Id
	 * @var Order
	 */
	private $order;

	/**
	 * @ORM\ManyToOne(targetEntity="Category")
	 * @ORM\JoinColumn(name="my_category_id", referencedColumnName="id", onDelete="RESTRICT")
	 * @ORM\Id
	 * @var Category
	 */
	private $category;

}

If you use indexBy="category", it does not work. Why are the object property names used for referencing in most of the mapping, but for indexBy you have to use the db field name? It is nowhere mentioned in the docs.
I didnt test this with non-association properties as indexBy.






[DDC-3398] PersistentCollection doesn't check that Entity is managed before scheduling