[DDC-3065] Generated 'IN' clause doesn't handle 'null' values (needs to add 'IS NULL' check) Created: 03/Apr/14  Updated: 03/Apr/14

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

Type: Bug Priority: Critical
Reporter: Sam Adams Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: IN, null, orm

Issue Links:
Dependency
depends on DDC-3067 [GH-999] DDC-3065 null value in in cr... Resolved
Reference
is referenced by DDC-3066 [GH-998] DDC-3065 null value in in cr... Resolved

 Description   

BasicEntityPersister::getSelectSQL($criteria) first argument can take an array.
However, if that array contains an 'or' structure like so:

array(
  'mycol'=>array(
    'couldbethis','orthis',null
  )
);

it is converted into:

mycol IN (?)

With the final query looking like:

WHERE mycol IN ('couldbethis','orthis',null)

The problem is, mysql will never be able to match the null.

Possible change to getSelectConditionStatementSQL method:

        if (is_array($value)) {
            $in = sprintf('%s IN (%s)' , $condition, $placeholder);
            $nullKey = array_search(null, $value, true);

            if ($nullKey) {
                return sprintf('(%s OR %s IS NULL)' , $in, $condition);
            } else {
                return $in;
            }
        }

resulting in a final query like:

WHERE (mycol IN ('couldbethis','orthis',null) OR mycol IS NULL)


 Comments   
Comment by Marco Pivetta [ 03/Apr/14 ]

Please see https://github.com/doctrine/doctrine2/pull/998 - I applied your suggested fix and tested it carefully

Comment by Doctrine Bot [ 03/Apr/14 ]

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





[DDC-2953] ArrayHydrator: Not all items hydrated while orderBy Created: 05/Feb/14  Updated: 06/Feb/14

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

Type: Bug Priority: Critical
Reporter: Mariusz Jaskółka Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: array, hydration
Environment:

Linux and Windows, PHP5


Attachments: File ArrayHydrator.php     File Array_Hydrator_4.2.php     File Array_hydrator_4.2_bugfix.php    

 Description   

I will explain the problem using example and pseudo-code:

I have query like that:
SELECT (...) FROM order LEFT JOIN person LEFT JOIN identifier (...) order by (...)

The rows returned by query are following (the order is very important):
order_id|person_id|identifier_id|
12 |21 |33 |
12 |21 |34 |
11 |21 |35 |
11 |21 |33 |
11 |21 |34 |
12 |21 |35 |

After hydration the result is like:
result[0][person][identifier][0][id]=33
result[0][person][identifier][0][id]=34
result[1][person][identifier][0][id]=35
result[1][person][identifier][0][id]=34

But it should be:
result[0][person][identifier][0][id]=33
result[0][person][identifier][0][id]=34
result[0][person][identifier][0][id]=35
result[1][person][identifier][0][id]=35
result[1][person][identifier][0][id]=34
result[1][person][identifier][0][id]=33

The reason is that ArrayHydrator::_identifierMap contains only object id and parents object id. In may example there is difference in parents parent (grandparent) id.



 Comments   
Comment by Marco Pivetta [ 05/Feb/14 ]

I've started work on this at https://github.com/doctrine/doctrine2/pull/933

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

This is how I temporary solved the issue, maybe it can help (attachment).

Comment by Marco Pivetta [ 06/Feb/14 ]

Mariusz Jaskółka can you provide a diff with current master? This seems to be based off 2.3 or previous versions...

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

Version 2.4.2 oryginal file and bugfix

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

Oh sorry it is version 2.4.1 (composer downloaded that version for me).
I hope it will be ok.

Comment by Marco Pivetta [ 06/Feb/14 ]

Mariusz Jaskółka thanks! I'm trying it right now

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

I added one dimention to $this->_identifierMap to be sure that all object's children's keys will be mapped separately.

Comment by Marco Pivetta [ 06/Feb/14 ]

Mariusz Jaskółka, I've applied your hotfix at https://github.com/doctrine/doctrine2/commit/c05921032ff6947daca2d7275031e5cde4700634 and the tests seem to pass on my system and on travis. You may want to check it out and see if it works for your use case.

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

It works for my use case correctly. You apparently forgot to remove/comment line 82 which is not necessary now.

Comment by Marco Pivetta [ 06/Feb/14 ]

Mariusz Jaskółka fixed, thanks!





[DDC-2800] Something wrong with documentation generation Created: 18/Nov/13  Updated: 02/Apr/14

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

Type: Documentation Priority: Critical
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The ArrayCollection has a matching() function, but it does not show in the API docs. http://www.doctrine-project.org/api/common/2.4/class-Doctrine.Common.Collections.ArrayCollection.html



 Comments   
Comment by Steve Müller [ 01/Apr/14 ]

Flip The collection API has moved to its own repo anyways now and there currently is no API generation for this, aswell as other subprojects like annotations etc. But the matching() method exists in 2.3 branch, where the repos were not separated, yet.

http://www.doctrine-project.org/api/common/2.3/source-class-Doctrine.Common.Collections.ArrayCollection.html#463-498

Do we need to keep this ticket open?

Comment by Flip [ 02/Apr/14 ]

I think so because no new documentation is generated for subprojects.

Expected: http://www.doctrine-project.org/api/collections/2.4/ (or any other latest version if the subprojects have seperate versioning)





[DDC-2332] [UnitOfWork::doPersist()] The spl_objact_hash() generate not unique hash! Created: 05/Mar/13  Updated: 30/May/13

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

Type: Bug Priority: Critical
Reporter: Krisztián Ferenczi Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony 2.1.8, php 5.4.7 and php 5.4.12, Windows 7


Attachments: Text File hashlogs.txt    

 Description   

I created fixtures and some data was inserted many times without calling the Task entity PrePersist event listener.

I printed the used and generated hash and I saw a Proxies_CG_\Asitly\ProjectManagementBundle\Entity\User hash equal a Task entity hash!



 Comments   
Comment by Marco Pivetta [ 05/Mar/13 ]

Please provide either a code example or a test case. As it stands, this issue is incomplete

Comment by Benjamin Eberlei [ 05/Mar/13 ]

Are you calling EntityManager#clear() inbetween? Because PHP reuses the hashes. The ORM accounts for this.

Comment by Benjamin Eberlei [ 05/Mar/13 ]

This is not a reproduce case, i don't want to execute your whole project.

I want to know, what is the actual bug that you see? Can you just print a list of all the hashes? Because the hashes dont differ at the end, bu tjust somewhere in the middle.

Comment by Krisztián Ferenczi [ 05/Mar/13 ]

I attached a hashlogs.txt file. The last Task class hash is 0000000050ab4aba0000000058e1cb12 ( line 3 129 )

This is not unique, view the line 2 760 . The Task is not being saved and the program don't call the prePersist listener. The "UnitOfWork" believe the entity has been saved because the isset($this->entityStates[$oid]) is true. But it is an other entity.

Comment by Krisztián Ferenczi [ 06/Mar/13 ]

The EntityManager::clear() fix the problem, but this is not "good" and "beautiful" solution. Shows no sign of that conflicts were and this is causing the problem. I was looking for the problem 7 hours.





[DDC-3088] EntityManager::clear doesn't working with inserting Created: 16/Apr/14  Updated: 16/Apr/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: Adrian Ch Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.4.25-1+sury.org~precise+2 (cli) (built: Feb 12 2014 10:45:30)
Symfony version 2.4.2 - app/dev/debug



 Description   

It looks like EntityManager's clear() method doesn't remove objects that was persisted during script execution.

Bellows are two functions. First one insert 10.000 records and use clear after each flush that should remove objects from memory, but instead of that memory usage growths in each iteration. There isn't any other reference for this objects.

I've checked how it works for reading and with clearing it works perfectly - script uses only constant memory.

 
    private function testInserting($em, $entityClass, $batchSize, $startMemoryUsage)
    {
        for ($i = 1; $i <= 10000; ++$i) {

            $item = new $entityClass();
            $item->setName($i);
            $item->setPresentation($i);
            $em->persist($item);

            if ($i % $batchSize == 0) {
                $em->flush();
                $em->clear();

                $currentMemoryUsage = memory_get_usage();
                printf("%d:\n\t%.2f MB (%.2f MB)\n", $i, $currentMemoryUsage /1024 / 1024, ($currentMemoryUsage - $startMemoryUsage) / 1024 / 1024);
            }
        }
    }
    
    
private function testReading($em, $entityClass, $batchSize, $startMemoryUsage)
    {
        $q = $em->createQuery("select i from $entityClass i");
        $iterableResult = $q->iterate();

        $i = 0;
        while (($row = $iterableResult->next()) !== false) {
            $em->clear();
            if ($i % $batchSize == 0) {
                $currentMemoryUsage = memory_get_usage();
                printf("%d:\n\t%.2f MB (%.2f MB)\n", $i, $currentMemoryUsage /1024 / 1024, ($currentMemoryUsage - $startMemoryUsage) / 1024 / 1024);
            }

            $i++;
        }
    }
    

My results:

1) Reading without clearing ($em->clear(); removed)

0:
22.89 MB (2.63 MB)
1000:
33.41 MB (13.15 MB)
2000:
44.04 MB (23.78 MB)
3000:
53.50 MB (33.24 MB)
4000:
65.13 MB (44.86 MB)
5000:
74.81 MB (54.55 MB)
6000:
84.27 MB (64.01 MB)
7000:
97.96 MB (77.69 MB)
8000:
107.40 MB (87.14 MB)
9000:
117.17 MB (96.91 MB)
10000:
126.61 MB (106.35 MB)

2) Reading with using clear

0:
22.89 MB (2.63 MB)
1000:
26.25 MB (5.99 MB)
2000:
24.74 MB (4.48 MB)
3000:
26.72 MB (6.46 MB)
4000:
24.79 MB (4.52 MB)
5000:
26.76 MB (6.50 MB)
6000:
24.81 MB (4.55 MB)
7000:
26.77 MB (6.51 MB)
8000:
24.83 MB (4.57 MB)
9000:
26.81 MB (6.54 MB)
10000:
24.86 MB (4.60 MB)

3) Inserting without clearing

1000:
29.50 MB (9.24 MB)
2000:
37.76 MB (17.50 MB)
3000:
45.12 MB (24.86 MB)
4000:
54.34 MB (34.07 MB)
5000:
61.79 MB (41.53 MB)
6000:
69.09 MB (48.82 MB)
7000:
76.40 MB (56.13 MB)
8000:
83.75 MB (63.48 MB)
9000:
95.64 MB (75.37 MB)
10000:
102.98 MB (82.71 MB)

4) Inserting with using clear

1000:
27.90 MB (7.63 MB)
2000:
34.64 MB (14.37 MB)
3000:
40.43 MB (20.17 MB)
4000:
48.20 MB (27.93 MB)
5000:
54.12 MB (33.85 MB)
6000:
59.89 MB (39.63 MB)
7000:
65.67 MB (45.40 MB)
8000:
71.43 MB (51.16 MB)
9000:
81.51 MB (61.25 MB)
10000:
87.29 MB (67.02 MB)



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

Would be useful to see what the entity class looks like.

Additionally, the ORM version being affected is also needed.





[DDC-3079] preUpdate in EntityListener not run in transaction Created: 10/Apr/14  Updated: 10/Apr/14

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

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


 Description   

I have entity:

class Article{
	/**
	 * @ORM\OneToMany(targetEntity = "ArticleModule\Model\Entities\ArticlePhoto", mappedBy = "article", cascade = {"persist", "remove"}, orphanRemoval = TRUE)
	 * @ORM\OrderBy({"sequence" = "ASC"})
	 */
	protected $articlePhotos;
}

And Entity Listener with preRemove.

I call

$article->articlePhotos->clear();
...some changes with entity...
$em->flush();

preRemove in Entity Listener is called, BUT before Begin transaction...

I can do
$em->transactional(function(){}); then it's full in transaction..






[DDC-3083] Persist/Flush silently fails when CTI is applied on an existing table Created: 12/Apr/14  Updated: 13/Apr/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: Frank Liepert Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Given an existing table (= parent table) the integration of a new parent-child relationship with Class Table Inheritance (CTI) leads to a update problem.

First of all a child table is created with a foreign key to the parent table. Next, the discriminator column is added to the parent table. The discriminator map will be auto-generated.

The problem arises when trying to perform persist() and flush() on a child entity. Initially the child table is logically empty. However, the UnitOfWork triggers updateTable() which will fail since there is nothing to update. Instead, an upsert should be performed.

Another sneaky thing is that the repository will return the child class with the updated data after calling flush() on the same request. On the next request the child class is returned with the data loaded from the persister. Of course, the updated data is missing.



 Comments   
Comment by Marco Pivetta [ 13/Apr/14 ]

Frank Liepert do I understand this correctly if I say that you are trying to (pseudo) upcast an entity to a more specific subtype? That is unsupported by the ORM. Could you make just an example snippet of what you described in the issue?

Comment by Frank Liepert [ 13/Apr/14 ]

Marco Pivetta: You have understood really well. If you say that's not supported by the ORM then this is the answer. Still I think that upsert could solve solve the "problem" and I know that there are/have been discussions about upsert.

Right now I will continue to manually insert the missing rows in the child table. After this necessary step the ORM works as expected.

Nevertheless the real bug is that after persist() and flush() the entity manager returns the child object with the "persisted" data of the child table although there are in fact no rows in the child table.

$parentRepository = $em->getRepository('Parent');

$child = $parentRepository ->find(1);
$child->setChildPropertyA('foo');

$em->persist($child);
$em->flush();

$child = $parentRepository ->find(1);
var_dump($child->getChildPropertyA());
// string(3) "foo"

// But: There is no 'foo' in the child table!


/** 
 * NEW REQUEST
 */

$parentRepository = $em->getRepository('Parent');

$child = $parentRepository ->find(1);
var_dump($child->getChildPropertyA());
// NULL

Comment by Marco Pivetta [ 13/Apr/14 ]

Frank Liepert why are $child in the first request and $child in the second request different here? Are you manually changing the data at SQL level?

Comment by Frank Liepert [ 13/Apr/14 ]

Marco Pivetta as I have explained the persist() and flush() in the first request trigger an UPDATE command (Because there is already a row in the parent table?). Given that the child table was manually created before there are no rows on that table at that time and therefore nothing can be updated. Nevertheless the ORM triggers no error and $child looks like having been persisted. In the second request you'll notice that there haven't been persisted any of the data belonging to the child table.





[DDC-3085] NULL comparison are not supported for result variables in the HAVING clause Created: 15/Apr/14  Updated: 15/Apr/14

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

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


 Description   

the following DQL query fails saying that score does not point to a class:

SELECT u AS user, SUM(r.value) AS score
FROM User u
LEFT JOIN ResultEntry r WITH r.user = u
GROUP BY u
HAVING score IS NOT NULL AND score >= 5

When removing the condition score IS NOT NULL, the query is working fine. The score result variable can be used in other comparisons:

SELECT u AS user, SUM(r.value) AS score
FROM User u
LEFT JOIN ResultEntry r WITH r.user = u
GROUP BY u
HAVING score >= 5





[DDC-3070] [GH-1001] [DDC-3005] Defer invoking of postLoad event to the end of hydration cycle. Created: 04/Apr/14  Updated: 04/Apr/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 Strate:

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

Message:

This feature makes guarantee, that postLoad event fires after all associations are populated.
Test case also provided.






[DDC-3073] @Column options Created: 07/Apr/14  Updated: 07/Apr/14

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

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


 Description   

The documentation seems to lack a reference to the ability to set options for columns. See:
http://stackoverflow.com/a/11776153/1833322
http://stackoverflow.com/a/14221973/1833322
http://stackoverflow.com/a/18050298/1833322






[DDC-3062] [GH-997] [FIX] Allow to use ManyToMany with all operators Created: 31/Mar/14  Updated: 31/Mar/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 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.






[DDC-3063] Unexpected behavior with 'WHERE NOT IN' and empty array Created: 01/Apr/14  Updated: 01/Apr/14

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

Type: Bug Priority: Major
Reporter: Tim Stamp Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None
Environment:

CentOS, PHP 5.4, mysql



 Description   

I tried to set version to 2.4.0 but was prevented.

Assume the set 'n' contains 10 records, all with id > 0.

->andWhere('n.id NOT IN (:ids)')->setParameter('ids', [])
returns 0 records.

->andWhere('n.id NOT IN (:ids)')->setParameter('ids', [0])
returns 10 records.


 Comments   
Comment by Marco Pivetta [ 01/Apr/14 ]

This is a simple misunderstanding of how SQL IN() works

Comment by Tim Stamp [ 01/Apr/14 ]

You're right that its invalid SQL, but this is DQL. In SQL this would raise an error, in DQL it says nothing and returns nothing.

Isnt there a way to check if a statement has caused this error?

Comment by Marco Pivetta [ 01/Apr/14 ]

Tim Stamp yeah, when using IN() and NOT IN() you should actually check if the parameters are empty or not before adding the clause.

Comment by Steve Müller [ 01/Apr/14 ]

It's still weird that no error is raised by that. Tim Stamp can you check what SQL is generated by your query?

Comment by Steve Müller [ 01/Apr/14 ]

Hehe I think I got the problem. It might be DBAL related. See:

https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/SQLParserUtils.php#L140
https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/SQLParserUtils.php#L169

Looks like the implementing person did that by intention but don't ask me why.

Comment by Marco Pivetta [ 01/Apr/14 ]

Thats to avoid having an SQL statement like

SELECT * FROM foo WHERE bar IN()

, which is invalid.

Indeed, the NOT IN() case is not contemplated by that.

Comment by Steve Müller [ 01/Apr/14 ]

Just wondering if that kind of implementation isn't changing expectations because it looks like IN(NULL) will select all NULL rows then, even though this is not explicitly requested by the user. I don't care really TBH but this behaviour is not very transparent to the user. Personally I would like to see an error instead... Then at least I know what's going on and can fix that by additional checks instead.

Comment by Marco Pivetta [ 01/Apr/14 ]

Makes sense. Re-opening.

Comment by Steve Müller [ 01/Apr/14 ]

The question is if we can change this behaviour without breaking applications that rely on the current one. Because changing the code to throw an error breaks applications that insist on returning 0 rows for an empty array. I don't know what rules apply here concerning BC. What do you think Marco Pivetta?

Comment by Marco Pivetta [ 01/Apr/14 ]

Steve Müller existing apps should do following anyway:

if ($productIds) {
    $qb->andWhere('p.id IN (:productIds)')->setParameter('productIds', $productIds);
}

If they are not, that's most likely a bug in their codebase.

Comment by Steve Müller [ 01/Apr/14 ]

Agree. Was just wondering about what we can expect and what we can't expect.





[DDC-3055] table not escaped in orm:schema-tool:update if table already exists and needs to be altered Created: 27/Mar/14  Updated: 27/Mar/14

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

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


 Description   

the schema tool had to alter a table which name needs to be escaped (and was properly configured to do so). this didnt work because the table name wasnt escaped. completely deleting the table in the db let the schema tool generate the correct querys with escaped table names.



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

Hilz Simon did you try this with master as well?





[DDC-3054] [GH-991] Ability to define custom functions with callback instead of class name Created: 27/Mar/14  Updated: 27/Mar/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 mnapoli:

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

Message:

Right now the only way to define custom DQL functions is by giving the class name, and Doctrine will create the class:

```php
$config->addCustomNumericFunction('FOO', 'My\Custom\DqlFunction');
```

This is very limiting when the custom functions has dependencies, for example it can't be created by a DI container.

The approach I have taken here is very simple: it allows to define a callback instead of the class name: the callback will be called and it should return the instance:

```php
$config->addCustomNumericFunction('FOO', function($funcName)

{ return new My\Custom\DqlFunction($funcName); }

);
```

On a side note, I think it would be great to generalize that approach because currently there are a lot of places where the same constraints apply.






[DDC-3056] Return value mismatch between code under HHVM and Zend Created: 28/Mar/14  Updated: 28/Mar/14

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

Type: Bug Priority: Major
Reporter: Andy hunt Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: hhvm, orm, paginator
Environment:

Two environments:
LAMP stack with PHP 5.4.25 on Ubuntu 12.04
HHVM 3.0.0.-dev (rel) ob Ubuntu 12.04



 Description   

The following code produces differing results under Zend and HHVM runtimes.

// $all::build uses the query builder to select all entities of a type
/** @var \Doctrine\ORM\Query $query **/
$query = $all->build($qb);
$query->setMaxResults($pageSize)->setFirstResult($start);

$paginator = new Paginator($query);
$results = array_values((array)$paginator->getIterator());

Under Zend, $results is a 1-dimensional array containing N elements:
[1, 2, 3].

Under HHVM, $results is a 2-dimensional array containing a single array, containing N elements:
[ [1,3,3] ]



 Comments   
Comment by Christophe Coevoet [ 28/Mar/14 ]

I suggest reporting it to the HHVM team as a bug

Comment by Marco Pivetta [ 28/Mar/14 ]

Also: why are you using an array cast and not iterator_to_array?

Comment by Christophe Coevoet [ 28/Mar/14 ]

@Marco this should be equivalent. Casting a Traversable to array should traverse it. If HHVM does not do it, it is a bug.

Comment by Marco Pivetta [ 28/Mar/14 ]

Christophe Coevoet not really: http://3v4l.org/Z3t4t





[DDC-3058] [GH-993] Update JoinColumn.php Created: 28/Mar/14  Updated: 28/Mar/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 KamilKopaczyk:

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

Message:

If $referencedColumnName = 'id' by default, it doesn't make sense to make checks like:
```php
if (empty($joinColumn['referencedColumnName'])) {
```
(ClassMetaDataInfo file)


Considering you map your column
```
@ORM\JoinColumn(onDelete="CASCADE")
```
You'll get JoinColumn with 'id' value, which doesn't let doctrine use naming strategies for referenced column names






[DDC-3044] [GH-986] Add last modified time for metadata Created: 22/Mar/14  Updated: 22/Mar/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 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.






[DDC-3052] [GH-989] Fix the problem when the lifecycle event can be triggered more then once... Created: 26/Mar/14  Updated: 26/Mar/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 dyangrev:

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

Message:

We recently saw the postUpdate event get trigger multiple time incorrectly, it typically happens when flushing a set of entities persisted whose listener persist and flush another type of entity in it.

Php passes variables to foreach by value, for the function executeUpdates in the UnitOfWork, for example, entities in the $this->entityUpdates could be updated and unset in the listener of the first entity, while them will be updated and trigger listeners again when the process of first entity finishes (although they have already been unset from $this->entityUpdates). Similar for executeInsertion and executeDeletion.






[DDC-3046] The flushed data is not available immediately for querying Created: 25/Mar/14  Updated: 25/Mar/14

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

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

ubuntu 13.10, mysql 5.5.35



 Description   

Doctrine's persisted data is not accessible by other queries immediately, for details see http://stackoverflow.com/questions/22618689/doctrines-persisted-data-is-not-accessible-by-other-queries-immediately






[DDC-3029] DISTINCT , ORDER BY AND Limit in SQL Server Created: 14/Mar/14  Updated: 14/Mar/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: Michał Banaś Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File SQLServerPlatform.php    

 Description   

I don't know if I should report it here , becouse error is in SQLServerPlatform.php file.
basicaly Distinct includes ROWNUM()
So if you add distinct in DQL it will be translated to "select distinct ...... , Rownum()" - which is always distinct offcource.

Here is original version
protected function doModifyLimitQuery($query, $limit, $offset = null)
{
if ($limit > 0) {
if ($offset == 0)

{ $query = preg_replace('/^(SELECT\s(DISTINCT\s)?)/i', '\1TOP ' . $limit . ' ', $query); }

else {
$orderby = stristr($query, 'ORDER BY');

if ( ! $orderby)

{ $over = 'ORDER BY (SELECT 0)'; }

else

{ $over = preg_replace('/\"[^,]*\".\"([^,]*)\"/i', '"inner_tbl"."$1"', $orderby); }

// Remove ORDER BY clause from $query
$query = preg_replace('/\s+ORDER BY(.*)/', '', $query);
$query = preg_replace('/^SELECT\s/', '', $query);

$start = $offset + 1;
$end = $offset + $limit;

$query = "SELECT * FROM (SELECT ROW_NUMBER() OVER ($over) AS doctrine_rownum, $query) AS doctrine_tbl WHERE doctrine_rownum BETWEEN $start AND $end";
}
}

return $query;
}
In Attachenment there is a fixed version of this file.






[DDC-3016] Criterias do not work with embeddables when matching in memory Created: 07/Mar/14  Updated: 12/Mar/14

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: Matthieu Napoli Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When using criterias and doing the matching on a collection already loaded in memory, it will not work if filtering on embeddable objects.

Example:

    $criteria = new Criteria();
    $criteria->andWhere($criteria->expr()->eq('actions.view', true));

    $authorizations = $this->authorizations->matching($criteria);

Here the ClosureExpressionVisitor will try to get the property named >actions.view instead of >actions->view.

PHPUnit_Framework_Error_Notice : Undefined property: Tests\...\Model\ArticleAuthorization::$actions.view





[DDC-3025] Schema tool UPDATE or CREATE not generate decimal precision and scale for ID element Created: 12/Mar/14  Updated: 12/Mar/14

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

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


 Description   

FYI. I don't use doctrine but with symfony2, and only use .yml or .xml mapping. Not yet try with annotation.

These commands :

php app\console doctrine:schema:update
php app\console doctrine:schema:create

Will not generate id's precision and scale for this kind of mapping :

<doctrine-mapping .....>
  <entity name="Namespace\MyBundle\Entity\MyData" table="my_data">
    <id name="id" type="decimal" column="id" precision="x" scale="y">
      <generator strategy="IDENTITY"/>
    </id>
    <field ... />
  </entity>
</ ....>

Suggested changes :

  • Doctrine\ORM\Mapping\Driver\YamlDriver.php
  • Doctrine\ORM\Mapping\Driver\XmlDriver.php





[DDC-3007] ManyToMany does not respect all column attributes for the jointable Created: 03/Mar/14  Updated: 03/Mar/14

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

Type: Bug Priority: Major
Reporter: Michael Kühn Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Given following 2 entities:

<?php
class Role {
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="UUID")
     * @ORM\Column(name="id", type="guid", nullable=false, unique=true, length=36, options={"fixed"=true})
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="roleList")
     */
    private $userList;
}
<?php
class User {
    /**
     * @ORM\Column(name="id", type="guid", nullable=false, unique=true, length=36, options={"fixed"=true})
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="UUID")
     */
    protected $id;

    /**     *
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="userList")
     * @ORM\JoinTable(name="user_role")
    protected $roleList;
}

It should create a table "user_role" with 2 columns which are CHAR(36).

But it ignores the Column-Attributes and creates a table "user_role" with 2 CHAR(255) columns.

This has various downsides:

  • It's unusable when using MyISAM, because of limited index size. (CREATE TABLE fails, see DBAL-423)
  • If using GUID-Type (see DBAL-423 with the changes from the linked ull request) and specify "length=36" and "fixed=true" on the Column-Annotation, no changes for the entity-tables itself are generated when running orm:schema-tool:update. However, there are still changes for the many-to-many-table generated (because internal "fixed" is false and length is unset) which represent the current state of the columns. These changes are always generated.





[DDC-3005] Events::postLoad fires without filled associations Created: 02/Mar/14  Updated: 10/Apr/14

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: Artur Eshenbrener Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When we load entities throw one dql query like this:

SELECT e, joined_link FROM Entity LEFT JOIN e.link joined_link

In event subscriber, subscribed to postLoad event for instances of Entity property "link" of entity does not contains fetched in same query joined entity, and does not contains proxy object.

Tell me if failing test case needed.



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

The postLoad event is fired without warranty that association entities/proxies will be set:

http://docs.doctrine-project.org/en/latest/reference/events.html#lifecycle-events

Comment by Artur Eshenbrener [ 03/Mar/14 ]

But why? This shounds like involuntary restriction, and I think it can be fixed. Will my PR with fix accepted, or collaborators don't want to change this behaviour?

Comment by Marco Pivetta [ 03/Mar/14 ]

Artur Eshenbrener triggering `postLoad` in the correct moment in time (when all dependencies are loaded) requires a lot of additional complexity to be inserted in various locations of the ORM.

Since `postLoad` is supposed to be used like `__wakeup` and in general for simple tasks, this kind of refactoring/rewrite would be an overkill.

Comment by Artur Eshenbrener [ 04/Mar/14 ]

> requires a lot of additional complexity to be inserted in various locations of the ORM.
Sounds like "It is very hard to implement, and no one want to do this"

> and in general for simple tasks, this kind of refactoring/rewrite would be an overkill.
Disagree with this. Why only simple? I need to deal with associations in this event. Without this I should inject whole EntityManager to my entity, but I dont want to do this.

And I forced to repeat the question: will PR with fix accepted or not?

Comment by Marco Pivetta [ 04/Mar/14 ]

Sounds like "It is very hard to implement, and no one want to do this"

Not really, the main problem here is performance, since hydration would have to be completely redesigned.
Yes, "too hard" is a good reason for something that is an edge case.

And I forced to repeat the question: will PR with fix accepted or not?

Sure thing! Just needs to avoid a massive rewrite though.

Comment by Marco Pivetta [ 04/Mar/14 ]

To give you some hints, Doctrine\ORM\Events::postLoad is triggered in https://github.com/doctrine/doctrine2/blob/15432fc55f83c2d6ce8d9b86fd3139dd2a4fc328/lib/Doctrine/ORM/UnitOfWork.php#L2788, and Doctrine\ORM\UnitOfWork#createEntity() is used by all the various hydrators internally.

To ensure that Doctrine\ORM\Events::postLoad is triggered after an entity is fully loaded, the various hydrators must trigger the events after being sure that all data has been set, and that the entity is "ready" for use. That's some copy-paste work :\

Comment by Artur Eshenbrener [ 04/Mar/14 ]

I think the entry point is here: https://github.com/doctrine/doctrine2/blob/15432fc55f83c2d6ce8d9b86fd3139dd2a4fc328/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php#L140,
so, copy-paste work is not needed )

Comment by Artur Eshenbrener [ 05/Apr/14 ]

PR is ready: https://github.com/doctrine/doctrine2/pull/1001





[DDC-2995] Joined Inheritance Mapping and Filters Created: 22/Feb/14  Updated: 23/Mar/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Bojidar Hristov Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: orm


 Description   

Is there any reason why Inheritance Mapping IS LEFT JOINED not INNER JOINED?

When there is a filter and it's left joined it happens a record might not have parent table record. For example

Class B extends Class A.
Class A have column is_active | and filter activated with is_active = 1 condition.

Final query: LEFT JOIN parent_table s1_ ON p2_.id = s1_.id AND (s1_.is_active = '1')

Record 1 have is_active = false, so result set looks like this:

table_b | table_a
id | id is_active discriminatorColumn
1 | null null null

and occurs exception: The discriminator column ... is missing for ....



 Comments   
Comment by Marco Pivetta [ 22/Feb/14 ]

JTI MUST be left-joined, since not every subclass of the root of the inheritance causes inserts on all of the inheritance tables.

What is the DQL query that is causing the problem?

Comment by Bojidar Hristov [ 22/Feb/14 ]

Hello Marco, I don't query from parent table, but from child. No sense to be LEFT JOINED.

DQL is something like that:

SELECT class1, class2 FROM Class1 class1 JOIN class1.class2 class2;

(Class2 extends Class3)
Class3 have is_active column.

And following filter:

public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias) {
if (!$targetEntity->reflClass->implementsInterface('ActivateableInterface'))

{ return ""; }

return $targetTableAlias . '.is_active = ' . $this->getParameter('isActive');
}

Filter condition is added in LEFT JOINED parent_table. Full example SQL:
SELECT ....
FROM class1 c1
INNER JOIN class2 c2 ON c1.c2_id = c2.id
LEFT JOIN table3 c3 ON c2.id = c3.id AND (c3.is_active = '1')

Comment by Marco Pivetta [ 26/Feb/14 ]

There are two possible solutions here:

  • verify if the selected entity is a leaf of a JTI, and use INNER JOIN on that if possible (probably not optimal, since the selection may be part of a LEFT JOIN itself)
  • add filtering on the discriminator column

Bojidar Hristov can you provide a failing test case to make it easier to work on this?

Comment by Bojidar Hristov [ 26/Feb/14 ]

Yes. Here is it sample failing test.

http://pastebin.com/xi8uUNX5 - Parent Class
http://pastebin.com/XRZLbyGX - Child Class
http://pastebin.com/HuPFb98u - Assoc Class
http://pastebin.com/hGqRk74e - TestCase

Here it should found 0 records because ot JOIN and is_active = true filter.

Comment by Benjamin Eberlei [ 23/Mar/14 ]

Since filters are only available on the root, i guess inner join is really necessary here.





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

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

Type: Bug Priority: Major
Reporter: Dennis Væversted Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
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





[DDC-2990] [GH-956] Foreign association index names Created: 19/Feb/14  Updated: 23/Feb/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

Issue Links:
Reference
relates to DDC-2989 ORM should allow custom index names f... Open

 Description   

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

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

Message:

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






[DDC-2981] Multi get for second level cache (Doctrine Cache related) Created: 13/Feb/14  Updated: 13/Feb/14

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: None


 Description   

Hi every body!

I'm developing an application that is highly based on doctrine second-level cache feature.
Using memcache or redis as cache back-end, doctrine have to query thousand times for the cached values (especially on one-to-many and many-to-many associations).
This introduces a lot of latency (and network traffic)...

I'm thinking to add to Doctrine\Common\Cache\Cache interface a method fetchMulti(array $keys) that fetches multiple items in one call. In this way doctrine orm can ask for many items with just one call (for example, here https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Cache/DefaultCollectionHydrator.php#L84 this feature can be very useful).

I have made some real-world tests and it can reduce highly the number of total queries (my app runs 190 cache requests instead of 900 cache requests)

Many vendors (memcache, redis, apc ecc) already offer this functionality, but with doctrine-cache we can't use it...

I'm going to implement this feature. Can it be accepted as a pull request?

It may be BC breaking:

  • it can be implemented adding a method inside Doctrine\Common\Cache\Cache interface (more BC breaking but more clean and elegant)
  • it can be implemented adding an interface Doctrine\Common\Cache\MultiCache and later CacheProvider can implement it (less BC breaking)


 Comments   
Comment by Marco Pivetta [ 13/Feb/14 ]

Adding a method to Doctrine\Common\Cache\Cache is not viable because of BC - a new interface would be ok

Comment by Asmir Mustafic [ 13/Feb/14 ]

ok, i agree with you.
But this forces me to check always here https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Cache/Region/DefaultRegion.php#L95 if $this->cache is instance of MultiCache

Comment by Marco Pivetta [ 13/Feb/14 ]

Asmir Mustafic or you build a MultiCacheRegion

Comment by Asmir Mustafic [ 13/Feb/14 ]

It can be a good approach. I will try it.
I'm thinking to provide a default implementation of fetchMulti directly inside CacheProvider that internally loops over each key and call CacheProvider::fetch($id) to fetch its value.
Later i will overwrite this behavior inside vendor specific driver (ApcCache, RedisCache...)





[DDC-2983] TCI association not getting hydrated into sql statement Created: 14/Feb/14  Updated: 23/Mar/14

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

Type: Bug Priority: Major
Reporter: Machete Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

MySQL, using DoctrineORMModule (zf2 integration)



 Description   

/**
 * @ORM\Entity
 * @ORM\Table(name="base")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discriminator", type="string")
 * @ORM\DiscriminatorMap({
 * "a" = "A",
 * "b" = "B",
 * })
 */
class Base
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
}

/**
 * @ORM\Entity
**/
class A extends Base {
    /**
     * @ORM\ManyToOne(targetEntity="B", inversedBy="as")
     */
    protected $b;

    /**
     * @ORM\OneToMany(targetEntity="C", cascade={"persist"})
     */
    protected $cs;
}

/**
 * @ORM\Entity
**/
class B Extends Base {
    /**
     * @ORM\OneToMany(targetEntity="A", mappedBy="b")
     */
    protected $as;
}

/**
 * @ORM\Entity
**/
class C {
  // ...
}

Doing this:

$a = new A();
$b = new B();

$a->setB($b);
$b->addA($a);

var_dump($a->getB()); // outputs B (b not null!)
var_dump($b->getAs()) // outputs A (private $_elements => [0] class B)

$em->persist($a);
$em->persist($b);
$em->flush();

Leads to

integrity constraint violation, b_id can not be null

aka

INSERT INTO a (id, b_id), (123, null);

I have no idea why this happens. This works:

$a = new A();
$b = new B();

$a->setB($b);
$b->addA($a);

var_dump($a->getB()); // outputs B (b not null!)
var_dump($b->getAs()) // outputs A (private $_elements => [0] class B)

$em->persist($a);
$em->flush();
$em->persist($b);
$em->flush();


 Comments   
Comment by Benjamin Eberlei [ 23/Mar/14 ]

This most likely happens because the UnitOfWork tries to set the owner and reverse incorrectly due to an ordering issue.





[DDC-2982] [GH-954] Multi Get support for Second Level Cache Created: 14/Feb/14  Updated: 23/Mar/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: 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/954

Message:

Hi!
As discussed [here](http://www.doctrine-project.org/jira/browse/DDC-2981) i have implemented some kind of multi-get for second level cache implementation.

I have also created a PR to doctrine/cache component (see https://github.com/doctrine/cache/pull/29) that enables this feature at driver cache level.






[DDC-2973] [GH-949] Add a default lock mode to the EntityManager Created: 10/Feb/14  Updated: 10/Feb/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 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!






[DDC-2954] Paginator loses items Created: 05/Feb/14  Updated: 12/Feb/14

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

Type: Bug Priority: Major
Reporter: Mariusz Jaskółka Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: Pagination, Paginator
Environment:

Linux and Windows, PHP 5, Oracle(OCI8)


Attachments: File LimitSubqueryOutputWalker.php     File LimitSubqueryOutputWalker_bugfix.php    

 Description   

Sometimes when when I use Paginator (Doctrine\ORM\Tools\Pagination\Paginator)

  • with query contains orderBy
  • with $fetchJoinCollection = true
  • lot of joins with toMany associations

there are too few items in result (no, it is not the end of list). There two situations:
1. I have four items on page 1 and two items on page 2 (pageLimit is 5). It is no so bad
2. I have four items on page 1 and there is no page 2 (while there should be 5 all items). This is very bad because I lose one item.

------------------------------------------------------------------
EDIT:
In function Paginator::getIterator there is variable $ids. In my situation it contains five numbers [34,26,34,15,12]. There is duplicated value 34 but ids of top-level entities should be distinct (as far as we do not use CROSS JOIN, or maybe I am wrong).

The Paginator::count function works correctly, it does not count duplicated values twice.

Statement that gets $ids is like following:
SELECT a.* FROM (SELECT DISTINCT ID2, BEGINTIME70 FROM (...) dctrn_result ORDER BY BEGINTIME70 DESC) a WHERE ROWNUM <= 5

------------------------------------------------------------------
EDIT 2 - Bugfix description:
The result items of the query is not unique because of
"SELECT DISTINCT col_with_id, order_by_column (...) ORDER BY order_by_column".
If we had items like following:
(1,A)
(1,B)
(1,B)
(2,C)

After DISTINCT operation the result would be:
(1,A)
(1,B)
(2,C)

But we want to have unique firs column, not pairs. That's why we should do "ORDER BY" before "DISTINCT" - not in the same time.
Please confirm if the solution is correct.



 Comments   
Comment by Marco Pivetta [ 05/Feb/14 ]

Mariusz Jaskółka this needs more details

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

OK, I will try to find out where the problem is.

Comment by Mariusz Jaskółka [ 06/Feb/14 ]

I have edited description, maybe additional information will help.

Comment by Mariusz Jaskółka [ 07/Feb/14 ]

I send the bugfix in attachment. I will describe it soon.

Comment by Mariusz Jaskółka [ 07/Feb/14 ]

Bugfix version 2 - previously I did not notice that oracle loses order after DISTINCT operation. Thus I used GROUP BY.

Comment by Mariusz Jaskółka [ 11/Feb/14 ]

I do not know if I can change status of this issue from "Awaiting Feedback". I can not see such option





[DDC-2955] [GH-933] [WIP] DDC-2953 Created: 05/Feb/14  Updated: 05/Feb/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 Ocramius:

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

Message:

This PR tries to fix DDC-2953 (http://www.doctrine-project.org/jira/browse/DDC-2953).

tl;dr: when the results are not sorted by root entity identifier, the array hydrator swallows some output.






[DDC-2940] [GH-922] Two hooks for DoctrineBundle to allow ContainerFilterCollection Created: 29/Jan/14  Updated: 29/Jan/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 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.






[DDC-2945] [GH-925] [DDC-2310] [DDC-2675] [2.4] Fix SQL generation on table lock hint capable platforms Created: 31/Jan/14  Updated: 31/Jan/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 deeky666:

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

Message:

Backport of PR https://github.com/doctrine/doctrine2/pull/910 for 2.4 branch.






[DDC-2946] [GH-926] Feature/console em helper interface Created: 01/Feb/14  Updated: 01/Feb/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 timdev:

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

Message:



 Comments   
Comment by Doctrine Bot [ 01/Feb/14 ]

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





[DDC-2929] Pessimistic lock on Query does not update the entity with the DB values if it's already cached Created: 22/Jan/14  Updated: 22/Jan/14

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: Renaud Drousies Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.4.13-1~dotdeb.1


Issue Links:
Reference
is referenced by DDC-1846 Pessimistic lock does not retreive la... Resolved

 Description   

When asking for a pessimistic lock through a Query object, the entities already in the cache are not refreshed with the latest values from the database (unless you set the Query::HINT_REFRESH hint)

Example:

        $em->beginTransaction();
        try {
            $bar = $em->createQuery('SELECT b FROM Foo:Bar b WHERE b.id = :id')
                        ->setParameter('id', 150)
                        ->getSingleResult();
            var_dump($bar->getAmount()); // Yields some positive value
            $bar->setAmount(0);
            $bar = $em->createQuery('SELECT b FROM Foo:Bar b WHERE b.id = :id')
                        ->setParameter('id', 150)
                        ->setLockMode(\Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE)
                        // ->setHint(\Doctrine\ORM\Query::HINT_REFRESH, true)
                        ->getSingleResult();
            var_dump($bar->getAmount()); // Yields 0

            $em->flush();
            $em->commit();
        } catch (\Exception $e) {
            $em->rollback();
        }

This is similar to DDC-1846

(Tested on 2.4.0 and 2.4.1)






[DDC-2930] Pessimistic locking using $em->find('Entity', $id, LockMode::PESSIMISTIC_WRITE) and $em->lock($entiy, LockMode::PESSIMISTIC_WRITE) differs in (not)refreshing entity state from DB Created: 23/Jan/14  Updated: 23/Jan/14

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: Jiri Kavalik Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

ubuntu 12.04, mysql, zf2



 Description   

When using pessimistic locking on MySQL(InnoDB tables) there is difference which surprised me:

$em->find('Entity', $id, LockMode::PESSIMISTIC_WRITE);

will reload entity state from DB even when entity was already managed in cache (implemented in DDC-2929)
So I supposed that

$em->lock($entiy, LockMode::PESSIMISTIC_WRITE);

will work alike even when in this case entity is sure already loaded and managed
But it is not the case, actual query log showed only

SELECT 1 FROM table WHERE id FOR UPDATE

If this difference is intended it would be nice to mention it in http://docs.doctrine-project.org/en/latest/reference/transactions-and-concurrency.html

As a workaround I use

$em->refresh($entiy);





[DDC-2922] Flushing new Entities reachable over several paths that do not all "cascade persist" Created: 17/Jan/14  Updated: 17/Jan/14

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

Type: Bug Priority: Major
Reporter: Matthias Pigulla Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Please consider the following associations:

  A <>--> B <-- C  

A is an "aggregate" type object w/ a OneToMany collection of Bs. This association is set to cascade persist operations.

C has a unidirectional OneToOne association to B as well.

Adding a new B to A's collection and flushing the EntityManager works - B is persisted (persistence by reachability).

However, when also creating a new C and pointing it to the new B, adding C to the EntityManager and then flushing leads to an exception because B is discovered as a new Entity through a relationship not set to cascade persist operations.

Obviously the problem here is that there are two paths through which we can discover new Entities. The UoW currently starts search from newly (explicitly) added Entities first before it walks through collections of already-managed entities.

I am unsure if it is just a documentation issue or a deeper problem?

If the UoW worked the other way round, the same problem would occur if the cascade persist was on the other association.

A solution would probably require the UoW to first collect all offending (new) Entities and the link they were discovered through, but later on remove Entities from this list if they are found through another association with the cascade persist option. The exception must not be thrown unless the whole reachability graph has been traversed.






[DDC-2918] get statements from ORM Created: 15/Jan/14  Updated: 15/Jan/14

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

Type: New Feature Priority: Major
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When doing `persist()` and then `flush()` the statements are not accessible anymore after the operation is done.

The EntityManager uses an EntityPersister. When looking at the BasicEntityPersister->executeInserts() a new statement is created but it's not saved as part of another object.
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php#L260

Benefit:
When having access to the statements afterwards, all the following methods would be available:
http://www.php.net/manual/en/class.pdostatement.php

Most interesting are rowCount and error related methods.



 Comments   
Comment by Steve Müller [ 15/Jan/14 ]

Flip AFAIK you can use an SQL Logger for this which has to be set in the connection. The ORM testsuite makes use of this, too. See this example: https://github.com/doctrine/doctrine2/blob/master/tests/Doctrine/Tests/ORM/Functional/OneToOneEagerLoadingTest.php#L155

Comment by Flip [ 15/Jan/14 ]

Yes sure, but using a logger will be a strange way to pipe it back into business logic.

For example it's possible to do remove() on a proxy so you don't know if the row was present or not.

or another situation ..

when dealing with concurrency .. somebody else might have deleted the row already ..





[DDC-2917] Inheritance using joins generates invalid SQL when used in SELECT queries with GROUP BY on Postgresql Created: 15/Jan/14  Updated: 15/Jan/14

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

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


 Description   

Say you have an entity with InheritanceType("JOINED"), some child entities defined in the DiscriminatorMap which include additional columns and are using PostgreSQL then try and execute a DQL query as below:

SELECT parententity FROM MyStuff\Entity\ParentEntity parententity GROUP BY parententity

Note: This is simplified for ease of reproduction, obviously the GROUP BY is pointless but in my actual query, which is significantly larger, the GROUP BY is actually useful.

PostgreSQL will give the following error:

SQLSTATE[42803]: Grouping error: 7 ERROR:  column "f2_.my_additional_column" must appear in the GROUP BY clause or be used in an aggregate function

Where f2_ is an alias in the actual SQL for one of the child entities.

This is because the SELECT in the actual SQL attempts to fetch the columns from the joined child entities but does not include them in the GROUP BY clause.

Bad SQL generated:

SELECT f0_.id AS id0, <f0_.* columns>, f2_.my_additional_column AS my_additional_column6
FROM parententitys f0_
LEFT JOIN childentity f2_ ON f0_.id = f2_.id
GROUP BY f0_.id, <f0_.* columns>

The SQL should be:

SELECT f0_.id AS id0, <f0_.* columns>, f2_.my_additional_column AS my_additional_column6
FROM parententitys f0_
LEFT JOIN childentity f2_ ON f0_.id = f2_.id
GROUP BY f0_.id, <f0_.* columns>, f2_.my_additional_column

N.b later versions of PostgreSQL don't require the GROUP BY on all the columns, just the primary key. Therefore the following would be sufficient:

SELECT f0_.id AS id0, <f0_.* columns>, f2_.my_additional_column AS my_additional_column6
FROM parententitys f0_
LEFT JOIN childentity f2_ ON f0_.id = f2_.id
GROUP BY f0_.id, f2_.id





[DDC-2914] [GH-910] [DDC-2310] Fix SQL generation on table lock hint capable platforms Created: 13/Jan/14  Updated: 31/Jan/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 deeky666:

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

Message:

SQL Server and SQL Anywhere use table lock hints for locking. ORM generates wrong SQL when used in conjunction with joins, in a table inheritance scenario or in a subquery. It places the table lock hints after the `JOIN` clauses, which is wrong. The table lock hints have to be placed after each table alias in the `FROM` clause.

*Example (current)*
```sql
SELECT t0.id FROM users t0 INNER JOIN profiles t1 ON t0.id = t1.user_id WITH (NOLOCK)
```

*Example (expected)*
```sql
SELECT t0.id FROM users t0 WITH (NOLOCK) INNER JOIN profiles t1 ON t0.id = t1.user_id
```

The testsuites fail big time at the moment because of that and I suppose ORM is more or less unusable at the moment for those platforms without this patch.

I needed to adjust a lot of tests which compared compiled DQL, to make use of the platforms specific lock hint clauses.
Also I did not add new tests because there are already so many tests, where this fails without this patch that this is not necessary IMO.



 Comments   
Comment by Doctrine Bot [ 31/Jan/14 ]

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





[DDC-2911] IndexBy doesn' work with arbitrary join Created: 13/Jan/14  Updated: 13/Jan/14

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

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


 Description   
        $statsQb = $em->createQueryBuilder()
            ->select('d AS date')
            ->from('MetalStatisticBundle:Day', 'd', 'd.date')
            ->leftJoin('MetalStatisticBundle:StatsDaily', 'sd', 'WITH', 'd.date = sd.date', 'sd.date')
            ->addSelect('sd AS stats')
            ->andWhere('sd.company = :company_id')
            ->setParameter('company_id', $company->getId())
            ->orderBy('sd.date', 'DESC')
            ->setMaxResults(10)

expected: array like

2012-10-10 => array(date => object, stats => object)
2012-10-09 => array(date => object)
2012-10-08 => array(date => object, stats => object)

got: exception Expected Literal, got 'BY'






[DDC-2901] entity-listeners are not propagated to children of mapped superclasses Created: 09/Jan/14  Updated: 09/Jan/14

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: Stuart Carnie Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mapping


 Description   

If I have event-listeners set on the subclass and mapped superclass, event-listeners will not be propagated, per this code. Conversely, lifecycle events are, per this






[DDC-2888] [GH-899] Add travis build matrix for all built-in PostgreSQL versions Created: 06/Jan/14  Updated: 06/Jan/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 deeky666:

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

Message:

[Travis now ships with PostgreSQL version 9.1, 9.2 and 9.3 built-in](http://about.travis-ci.org/blog/2013-11-29-postgresql-92-93-now-available/). We should extend our build matrix to test on all versions.






[DDC-2891] Impossible to pass a limit to a subquery Created: 07/Jan/14  Updated: 08/Jan/14

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

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


 Description   

It seems that passing the limit to a subquery is not working

 
$subquery = $em->createQueryBuilder()->from('...')->where('...')->setMaxResults(5);
$query = $em->createQueryBuilder()->from('...')->where(
   $qb->expr()->in('p.id', $subquery->getDQL())
);
$query->getQuery()->getResult();

The query works but the is no specified limit in the resulting SQL.
I am aware that DQL does not support the limits and offsets, so i guess there should be another way to get this working?



 Comments   
Comment by Steve Müller [ 08/Jan/14 ]

Can you please tell which database platform you are using? Because limiting results heavily depends on the platform used.

Comment by alex [ 08/Jan/14 ]

MySql

Comment by Steve Müller [ 08/Jan/14 ]

Hmmm I am not quite sure if the limit/offset is invoked for subqueries but I don't see why it shouldn't. Also I think this is not a DBAL issue because the limit/offset support for MySQL is the easiest we have on all platform. See: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php#L51-L63
The query doesn't have to be modified but instead only the limit clause is appended to the query. Can you maybe provide the generated SQL for that query?

Comment by alex [ 08/Jan/14 ]

I think if you try to build any query with QueryBuilder, set a limit to it with setMaxResults then call getDQL method, you should see that the output contains no info about limit.
So if you look at my code example , at $qb->expr()>in('p.id', $subquery>getDQL()), then you will see that the getDQL passes to the IN expression a query which already DOES NOT have limit. So this is the place where any info about limits and offsets gets lost.

So I fail to see what it has to do with any specific db engine,however I can provide the mysql resulting query if you want,though it looked perfectly normal to me,just lacks the LIMIT part.





[DDC-2881] [GH-895] Fix for no dot on Class Names Created: 04/Jan/14  Updated: 04/Jan/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 sinner:

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

Message:

If you work with PostgreSQL Schemas, You should filter the names of table to generate Correct name for PHP Classes. This way allow not write dots (.) as part of the Class Name.

Additionally, there is a variable ($schema) that must be contained in the class "Doctrine\DBAL\Schema\Table" on an $schema possible property but this is not available. (recomended)






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

Status: Awaiting Feedback
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: Benjamin Eberlei
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';
    }
}





[DDC-2875] [GH-890] [DBAL-563] Add general IDENTITY generator type support for sequence emulating platforms Created: 29/Dec/13  Updated: 31/Dec/13

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 deeky666:

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

Message:

This is a follow-up PR for https://github.com/doctrine/dbal/pull/428 as discussed in DBAL-563(http://www.doctrine-project.org/jira/browse/DBAL-563) which adds IDENTITY generator type support for platforms that do not natively support identity columns but can emulate them via sequences.
This replaces the current workaround for PostgreSQL `SERIAL` columns in favour of a more general approach. With this patch now IDENTITY generator can also be used with Oracle which did not work before. Future platforms can also make use of this approach if necessary.



 Comments   
Comment by Doctrine Bot [ 31/Dec/13 ]

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





[DDC-2870] Doctrine error when using SUM(a.id=1) as `ìdentifier`: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '=' Created: 22/Dec/13  Updated: 06/Jan/14

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

Type: Bug Priority: Major
Reporter: Maxim Geerinck Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql
Environment:

Symfony2 bundle



 Description   

Doctrine error when using SUM(a.id=1) as `ìdentifier`: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '='

I am trying to execute a query in doctrine that contains something like this

SUM(a.id = 1) as `1`
for some reasons it always gives me the following error:

[Syntax Error] line 0, col 15: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '='
This is the code i am using

$result = $em->getRepository('MyBundle:PlayerAction')
->createQueryBuilder('pa')
->select(array(
'SUM(a.id=1) as `1`,
SUM(a.id=2) as `2`,
SUM(a.id=3) as `3`,
p.playerName,
pa.timestamp'
))
->innerJoin('pa.action', 'a')
->innerJoin('pa.player', 'p')
->where('pa.timestamp > ?1')
->groupBy('p')
->setParameter(1, time() - $time)
->orderBy('p.playerName', 'ASC');






[DDC-2869] [GH-886] [DDC-1256] Fix applying ON/WITH conditions to first join in Class Table Inheritance Created: 22/Dec/13  Updated: 17/Feb/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 Strate:

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

Message:

Some related issues:
http://www.doctrine-project.org/jira/browse/DDC-1256
http://www.doctrine-project.org/jira/browse/DDC-2131

I think that applying custom user joins conditions to last join in CTI is ok because only in last join DB will know about all joined table aliases. And I can't see any other probles with this.

Tests are not passed, because, I think, problem in tests.

To be discussed, of course



 Comments   
Comment by Doctrine Bot [ 17/Feb/14 ]

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





[DDC-2865] [GH-882] Efficient counting on Criteria Created: 19/Dec/13  Updated: 02/Jan/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: 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/882

Message:

Hi,

This is an attempt to solve this very annoying issue: http://www.doctrine-project.org/jira/browse/DDC-2217

I'm not sure about my solution as I'm not really into Doctrine internals.

  1. Use case

I have a library that is based exclusively on Criteria API. A Paginator adapter uses an empty Criteria to count how many elements are in the collection. However, EntityRepository's matching method always initialize the whole collection into an ArrayCollection. This is unusable in most cases and make the API unusable for my use case.

  1. Solution

I've created a new LazyCollectionCriteria that implements an efficient count. I think the cleanest solution would be to add a method to the Selectable interface: with a count method. But I think this is not possible now, unfortunately.

If the solution seems nice to you, I'll write the tests.

ping @ocramius, @mac_nibblet and @thinkscape (this should make ZfrRest usable )






[DDC-2861] [GH-881] Fix persistence exception on a table with a schema on a platform without schema support Created: 18/Dec/13  Updated: 18/Dec/13

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 michaelperrin:

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

Message:

This PR solves two related issues with the use of a database schema on platforms (such as SQLite) that don't support schemas.

I discovered the issues when I generated the schema from my Doctrine entities on SQLite (for unit test purposes of my application) whereas my main application uses PostgreSQL.

This is one of my first PR on Doctrine, so sorry if I made some things in the wrong way and I'm open to discussion.

*First problem: table names dots are not converted in the ORM*

On a platform like SQLite, DBAL converts table names with dots (ie. a schema is declared) to double underscores.
However, the ORM doesn't do it, and persisting leads to an exception.

Example:

```
MyNamespace\Mytable:
type: entity
table: myschema.mytable

  1. ...
    ```

And then somewhere in the code:

```
$myTable = new MyNamespace\Mytable();
$entityManager->persist($myTable);
$entityManager->flush();
```

This doesn't work in the current version of Doctrine. The table is created as `myschema__mytable` but entities are unsuccessfully saved in `myschema.mytable`.

*Second problem: table names with reserved keywords in a database schema are not correctly escaped*

When a table name is declared as `myschema.order` (or any other reserved keyword), only the reserved keyword part is escaped when creating the table, leading to the creation of a table name like myschema__\`order\`, which is invalid and therefore fails.

*How this PR solves the problem*

The classmetadata now stores in 2 separated properties the name of the table and the name of the schema. The schema property was partially implemented but I now make a full use of it.

When metadata is read (from Annotations, YAML, ...), if the table name has a dot (`myschema.mytable`), it's splitted into 2 parts, and `myschema` is saved in the `schema` table property, and `mytable` is saved in the `name` table property, instead of storing the whole `myschema.mytable` in the `name` table property.

This allows to do specific things about schemas everywhere in Doctrine, and not splitting again parts everywhere it's needed.

By the way, the `schema` property can now fully be used.

For instance, these 2 YAML configurations are valid and do the same thing:

```
MyNamespace\Mytable:
type: entity
table: myschema.mytable
```

and:

```
MyNamespace\Mytable:
type: entity
table: mytable
schema: myschema
```

This was something which was not finished to be implented since Doctrine 2.0.

The Default quote strategy now converts back the schema and table names to a unique table name, depending on the platform (e.g. `myschema.mytable` if the platform supports schemas, and `myschema__mytable` otherwise).

As a result, there is no problem anymore and entities can be persisted without getting any exception.
I added some unit tests for this (the same unit tests failed before of course).

There's however a slight tradeoff on performance, as the `getTableName` of the `DefaultQuoteStrategy` class adds some tests to return the correct table name.

This solved these Doctrine issues: DDC-2825(http://www.doctrine-project.org/jira/browse/DDC-2825) and DDC-2636(http://www.doctrine-project.org/jira/browse/DDC-2636).

Again, this is one of my first PRs on Doctrine, so if there's anything wrong or if you have any question, feel free to comment this PR.

@Ocramius This PR is about what we talked about in DDC-2825(http://www.doctrine-project.org/jira/browse/DDC-2825)






[DDC-2851] Allow set custom collection initializer at runtime Created: 12/Dec/13  Updated: 12/Dec/13

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

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


 Description   

Use case: Company, Category, CompanyCategory entities. We are loading set of companies and should initialize Company.companyCategories collection with joined categories, which ordered by Company.title.

I cann't do it via Criteria API, it doesn't supports joins. + I should return same PersistentCollection instance (Company.companyCategories used in Symfony2 forms).

Current workaround:

    public function loadCompanyCategoriesCollectionForCompany(Company $company)
    {
        $companyCategories = $this->_em->createQueryBuilder()
            ->select('cc')
            ->from('OloloCompaniesBundle:CompanyCategory', 'cc')
            ->join('cc.category', 'c')
            ->addSelect('c')
            ->orderBy('c.title')
            ->where('cc.company = :company')
            ->setParameter('company', $company)
            ->getQuery()
            ->getResult()
        ;

        $coll = $company->getCompanyCategories();
        foreach ($companyCategories as $companyCategory) { /* @var $coll \Doctrine\ORM\PersistentCollection */
            $coll->hydrateAdd($companyCategory);
        }
        $coll->setInitialized(true);
    }

What would be nice: native API for setting custom initializers.






[DDC-2852] Enclose subquery with parenthesis in from clause (QueryBuilder) Created: 12/Dec/13  Updated: 12/Dec/13

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: Matthieu Pécro Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: from, orm, parenthesis, querybuilder,, subquery


 Description   

Hi

In QueryBuilder from clause, when argument is a QueryBuilder (not a string like a table), there are not parenthesis enclosure on the subquery.

Ex:
$subqb->select('myfield')->from('mytable');
$qb->from($sub, 'myalias)

DQL is : SELECT myfield FROM SELECT myField FROM mytable myalias. This is not working on MySQL.

It should be : SELECT myfield FROM (SELECT myField FROM mytable) myalias.



 Comments   
Comment by Christophe Coevoet [ 12/Dec/13 ]

I don't understand your statement This is not working on MySQL. after giving a DQL statement. MySQL does not support any DQL. It runs SQL.

And DQL does not support using a subselect in the FROM clause





[DDC-2841] Preload data for association Created: 06/Dec/13  Updated: 06/Dec/13

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: Przemyslaw Wrobel Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Consider two classes User and Address with one-to-many association.
I would like to preload addresses for given user object so that it will be accessible via getter method like this:

1. $user = $userRepository->find($userId);
2. load some of the addresses but not all
3. $user->getAddresses() should return those loaded in step 2

Currently the only solution for step 2 I found working is to write a DQL like this:
SELECT u, a
FROM User
INNER JOIN u.addresses a
WHERE u = :user AND a.foo = 1

When the data is hydrated it is assigned to the user object and thus accessible with $user->getAddresses (which normally would return all the addresess not only those with foo set)

The only problem is that the query in step 2 unnecessarily fetches all user data that was already fetched in step 1






[DDC-2839] [GH-869] Detach objects in original object data Created: 04/Dec/13  Updated: 05/Dec/13

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 tomphp:

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

Message:

The PR makes Doctrine ORM update the database when you execute something like this:

```php
// MyEntity.php

/**

  • @Entity
    */
    class MyEntity
    {
    // ...

/**

  • @Column(type="datetime")
    */
    private $created;

// ...

public function setCreated(\DateTime $created)

{ $this->created = $created; }

public function getCreated()

{ return $this->created; }

// ...
}
```

```php
// Current problem

$entity = $entityManager->find('MyEntity', 1);

$entity->getCreated()->setDate('2001-01-01');

$entityManager->persist($entity);

$entityManager->flush();

// At this point no changes have been made to the database!
```

The reason this doesn't work currently is because the array of original data stored in the UnitOfWork contains the actual DateTime object which is in the entity. When you update the object in the entity the original data is updated also so the entity are the original value are still equal and therefore the object is not seen as changed.

I have chosen to clone all objects rather than just DateTime object include more types are included in the future.



 Comments   
Comment by Doctrine Bot [ 05/Dec/13 ]

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





[DDC-2835] No Lock Hint on Joins Created: 03/Dec/13  Updated: 03/Dec/13

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: Paul Mansell Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Microsoft SQL Server 2008/2012



 Description   

There seems to be no lock hits added to the joins on a query. For example, take the following query :

SELECT w0_.name AS name0, w1_.name AS name1, c2_.name AS name2, count(w3_.id) AS sclr3 FROM workflow_request w3_ WITH (NOLOCK) INNER JOIN workflow_request_status w1_ ON w3_.status_id = w1_.id INNER JOIN workflow_action w0_ ON w3_.action_id = w0_.id LEFT JOIN workflow_transition w4_ ON w3_.transition_id = w4_.id INNER JOIN core_mno_account c5_ ON w4_.mno_account_id = c5_.id INNER JOIN core_mno c2_ ON c5_.mno_id = c2_.id LEFT JOIN workflow_state w6_ ON w3_.current_state_id = w6_.id WHERE w1_.ident IN GROUP BY w0_.name, w1_.name, c2_.name ORDER BY w0_.name ASC, w1_.name ASC, c2_.name ASC [["waiting"]]

the "with(nolock)" is only added to the FROM clause .... it should be added after each join too






[DDC-2838] Leaky abstraction when applying Criteria to hydrated/non-hydrated PersistentCollection Created: 03/Dec/13  Updated: 03/Dec/13

Status: Open
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: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 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






[DDC-2834] [GH-868] Added documentation section for Memcached Created: 02/Dec/13  Updated: 02/Dec/13

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 mnapoli:

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

Message:

The documentation only talked about Memcache, an old PHP extension that can now be safely replaced by Memcached.

I've add a section of documentation about Memcached because the code to have it working is not the same.



 Comments   
Comment by Doctrine Bot [ 02/Dec/13 ]

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





[DDC-2826] Add support for mapping collections of embeddable objects Created: 28/Nov/13  Updated: 08/Feb/14

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

Type: New Feature Priority: Major
Reporter: songoko songowan Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: collection, orm, value-objects


 Description   

In Hibernate we can do something like this:

    @Entity
    public class User {
       [...]
       public String getLastname() { ...}
    
       @ElementCollection
       @CollectionTable(name="Addresses", joinColumns=@JoinColumn(name="user_id"))
       @AttributeOverrides({
          @AttributeOverride(name="street1", column=@Column(name="fld_street"))
       })
       public Set<Address> getAddresses() { ... } 
    }
    
    @Embeddable
    public class Address {
       public String getStreet1() {...}
       [...]
    }

Basically a collection of value objects is mapped to a new table. Currently Doctrine2 is on its way to support value objects

However, this implementation won't support mapping a collection of objects to a new table and the only way to circumvent this issue is to treat the address an an entity and use an one-to-many unidirectional relationship through a many-to-many join table



 Comments   
Comment by Doctrine Bot [ 08/Feb/14 ]

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





[DDC-2824] [GH-863] The new configuration option: defaultQueryHints Created: 27/Nov/13  Updated: 02/Jan/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: 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 Strate:

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

Message:

I propose the new configuration option: `defaultQueryHints`, where developer can set array of hints, which will be applied to every query, created by doctrine. This option will be useful to set global AST walker, for example.






[DDC-2819] [GH-860] Mention SQL Anywhere in basic mapping documentation Created: 25/Nov/13  Updated: 25/Nov/13

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 deeky666:

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

Message:

Just for documentation completion of the new SQL Anywhere platform.



 Comments   
Comment by Doctrine Bot [ 25/Nov/13 ]

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





[DDC-2816] New event: pre-execute query Created: 25/Nov/13  Updated: 25/Nov/13

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: Artur Eshenbrener Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It would be useful to fire event just before each query executes. Listeners can set hints to query, for instance.






[DDC-2813] [GH-857] free more resources Created: 22/Nov/13  Updated: 23/Nov/13

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 Gladhon:

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

Message:

use unset to free resources better



 Comments   
Comment by Doctrine Bot [ 23/Nov/13 ]

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





[DDC-2809] [GH-853] Fix for PHP entity default values generated by EntityGenerator Created: 21/Nov/13  Updated: 21/Nov/13

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 patrickkostjens:

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

Message:

When specifying a default value for a column in the YAML, this value should be set in the entities that are generated by the EntityGenerator. The EntityGenerator looked for the default value in the wrong place of the field mapping and therefore defaults were never set. This issue has been fixed in this branch.



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

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





[DDC-2811] [GH-854] fix relative path to doctrine/common Created: 22/Nov/13  Updated: 23/Nov/13

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 ptarjan:

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

Message:

While testing your framework on HHVM I found this test doesn't pass because the path doesn't find what composer was installing into



 Comments   
Comment by Doctrine Bot [ 23/Nov/13 ]

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





[DDC-2799] [GH-850] Event listener to programmatically attach entity listeners. Created: 18/Nov/13  Updated: 25/Nov/13

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 FabioBatSilva:

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

Message:

This patch adds a event listener to programmatically attach entity listeners.

Especially useful to attach listeners to external bundles/modules..



 Comments   
Comment by Doctrine Bot [ 25/Nov/13 ]

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





[DDC-2797] [GH-848] eliminate duplicate placeholders in "walkComparison" function within Que... Created: 18/Nov/13  Updated: 18/Nov/13

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 bsahlhof:

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

Message:

...ryExpressionVisitor

I've run into an issue when using Criteria with QueryBuilder when Criteria uses multiple checks on same variable in different context, example:
field1 = value OR (field1 in values AND field2 = true)... what happens is field 1 placeholder is duplicated, and an error occures in code complaining about invalid # of parameters. The fix eliminates this issue, making sure parametername is unique.

I have not had time to check any other possible issues this may cause, but a review of the code doesn't appear to impact any other function.



 Comments   
Comment by Doctrine Bot [ 18/Nov/13 ]

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





[DDC-2795] the queryBuider Expr\Join class has a ON type but unsupported by the parser Created: 14/Nov/13  Updated: 14/Nov/13

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

Type: Bug Priority: Major
Reporter: Christophe Coevoet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: documentation, dql, querybuilder,


 Description   

The Doctrine\ORM\Query\Expr\Join class has 2 cosntants for the condition types: WITH and ON.

None of them are documented. The only place where WITH appear is the EBNF, which is outdated in the doc as it does not show arbitrary joins (added in 2.3) but only association joins.

and when looking at the EBNF in the code, I find 2 different ones (none of them matching the one given in the doc):

  • in Doctrine\ORM\query\Parser::Join:
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN"
         (JoinAssociationDeclaration | RangeVariableDeclaration)
         ["WITH" ConditionalExpression]

This is matching the implementation and ON is not supported.

  • in Doctrine\ORM\Query\AST\Join:
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression
         ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression]

This one is missing 2 features also missing in the doc (INDEX BY for associations, and arbitrary joins) and adds the support of ON which is not implemented.

What is the reason to have this ON constant in the query builder ? It is confusing to get a DQL parse exception when using it if it is there.

On a side note, what is the canonical source for the EBNF ? There is 2 different locations in the code (the phpdoc of parser methods and the phpdoc of AST nodes created by the parser), plus the doc. Shouldn't we try to limit the duplication and have a way to check the consistency of the doc ?






[DDC-2794] the Paginator does not support arbitrary join Created: 14/Nov/13  Updated: 23/Dec/13

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

Type: Bug Priority: Major
Reporter: Christophe Coevoet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: paginator


 Description   

Using the following query with the paginator fails:

SELECT u
FROM User u
JOIN Message m WITH m.author = u
WHERE m.status = 'draft' -- a condition justifying the join

The CountWalker and the CountOutputWalker both throw a exception saying "Cannot count query which selects two FROM components, cannot make distinction"

This message is wrong (I can make distinction here. Only User is selected in the result set) and confusing (I spent some time finding the second FROM before figuring it was related to the use of an arbitrary join instead of an association join).



 Comments   
Comment by Pierre-Antoine Pinel [ 23/Dec/13 ]

Hi,

I have the same issue.
My query is : SELECT entity FROM W\XBundle\Entity\X entity LEFT JOIN Z\YBundle\Entity\Y y WITH y.x = entity LEFT JOIN y.v v WHERE v.name LIKE :like

Is there a way to fix this issue ? I really need this to work with the Paginator.

Best,

Comment by Christophe Coevoet [ 23/Dec/13 ]

Why changing the status to "Awaiting feedback" ? It is not waiting for a feedback of the reporter to check the fix. It is an open ticket which does not have a fix yet





[DDC-2791] Constant value in JoinColumn Created: 13/Nov/13  Updated: 13/Nov/13

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: Pavel S. Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: joins, mapping, orm

Attachments: JPEG File realty_reference.jpeg    

 Description   

My situation:
I have realty entities (flat, house, ...) they have hundreds parameters, wich title places in REFERENCE table. For example House has a few floor materials (stone, wood, etc.) and I want to get them. But each parameter type defined by type_id field in REFERENCE table, for example for floor material is's 115. My raw SQL:
SELECT h.id,... FROM HOUSE h
LEFT JOIN object_detail mf /material_floor/ ON mf.realty_id = h.id AND mf.data_class = h.data_class AND mf.type_id = 115
LEFT JOIN Reference mfr ON mfr.city_id = h.city_id AND mfr.id = mf.detail_id

And its not possible to set type_id directly in join table






[DDC-2787] COALESCE() doesn't work with NOT IN() Created: 09/Nov/13  Updated: 09/Nov/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.4
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 try running the following query:

SELECT count(c.id) FROM my\model c WHERE COALESCE(c.up, 0) NOT IN( :parent_ids)

I get

Doctrine\ORM\Query\QueryException: [Semantical Error] line 0, col 118 near 'up, 0) NOT IN(': Error: Invalid PathExpression. Must be a StateFieldPathExpression.

When I run the query as straight SQL against the database, it works as expected. Is this something that can be fixed in Doctrine or is this syntax unsupported?






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

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





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

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






[DDC-2781] [GH-841] Enable saving native queries using ResultSetMappingBuilder. Created: 07/Nov/13  Updated: 02/Jan/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: 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 TheFrozenFire:

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

Message:

At present, a useful feature of ResultSetMappingBuilder, which creates the SELECT clause relevant to the built result set mapping, is unusable with named native queries.

This feature adds two additional, optional parameters to named native queries which stores an arbitrary string placeholder and an array of table aliases with the query.

Upon creation of the named native query, if the ResultSetMapping is a ResultSetMappingBuilder, and the placeholder is specified, the arbitrary string specified as the placeholder will be replaced with the output of ResultSetMappingBuilder::generateSelectClause(), passed the table aliases.

This allows native queries to be bootstrapped into an application as named queries, while also allowing the select clause to be automatically updated in the query as the metadata for the mapped entities changes.

Because native queries are not parsed in any way, a string placeholder is required to be able to interpolate the select clause into the query.






[DDC-2771] [GH-834] Add example use of repositoryClass in YAML Created: 01/Nov/13  Updated: 04/Nov/13

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 carlosbuenosvinos:

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

Message:



 Comments   
Comment by Doctrine Bot [ 04/Nov/13 ]

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





[DDC-2763] Inheritance. CTI & STI. Improve lazy load associated entity, when target entity in association mapping is not last leaf in class hierarchy. Created: 27/Oct/13  Updated: 27/Oct/13

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: Artur Eshenbrener Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance


 Description   

If we look inside documentation, we can see this:

There is a general performance consideration with Class Table Inheritance: If the target-entity of a many-to-one or one-to-one association is a CTI entity, it is preferable for performance reasons that it be a leaf entity in the inheritance hierarchy, (ie. have no subclasses). Otherwise Doctrine CANNOT create proxy instances of this entity and will ALWAYS load the entity eagerly.

I think it can be improved, if we will load only discriminator column value for resolve target class name, instead of loading whole entity. When we perform query from root entity, dicriminator value is already present in fetched database row.
What do you think?



 Comments   
Comment by Marco Pivetta [ 27/Oct/13 ]

Queries to fetch the discriminator column cannot be avoided (that's a limitation we can't workaround as far as I know).

What can be improved is avoiding instantiation of the joined results, and instead keep a proxy and a copy of the data for deferred hydration. That would allow avoiding recursive queries which are seen quite often when referencing the root of a STI/JTI

Comment by Artur Eshenbrener [ 27/Oct/13 ]

Queries to fetch the discriminator column cannot be avoided (that's a limitation we can't workaround as far as I know).

Of course, but fetching the discriminator value will produce less overhead than loading whole entity (with recursive loading joined entities). And, when you querying from root entity (with mapped sicriminator column), discriminator value already present in db result row (no need to extra query for dicriminator value).

What can be improved is avoiding instantiation of the joined results, and instead keep a proxy and a copy of the data for deferred hydration. That would allow avoiding recursive queries which are seen quite often when referencing the root of a STI/JTI

The result of my proposal will ability to get proxy class without loading whole entity.





[DDC-2767] ID property of MayToOne association has wrong type Created: 30/Oct/13  Updated: 07/Nov/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
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   

I'm seeing the following behaviour in some Doctrine code I'm writing:

$entity = array_pop($qb->getQuery()->getResult());
echo gettype($entity->getId()) . ' ' . $entity->getId();
// prints: integer 123

$association = $entity->getAssociation(); // unidirectional ManyToOne link to some other entity
echo gettype($association->getId()) . ' ' . $association->getId();
// prints: string 345

When I load the associated entity directly (via find() f.x.), it's ID has the integer type as expected, and the database structure looks correct, too.

I'm not entirely sure if this is a problem in my code or some issue in QueryBuilder or some other Doctrine component, but if someone could point me into the right direction, that would really be helpful.

I guess normally the type of the ID is not so important because you're not supposed to access it directly anyways, but I need to provide backward compatibility for a lot of code written against a different ORM API that provided exactly this behaviour.



 Comments   
Comment by flack [ 07/Nov/13 ]

After some research, the problem sounds kind of similar to

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

only that in my case, it's not a custom type, but a builtin one that is not working. But AFAICT, in both cases it's getting the ID from a proxy that is problematic





[DDC-2751] [GH-823] Elaborate description of the classIsNotAValidEntityOrMappedSuperClass ex... Created: 20/Oct/13  Updated: 02/Jan/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 spolischook:

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

Message:

...ception



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

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





[DDC-2733] DefaultQuoteStrategy BUG on Oracle Created: 10/Oct/13  Updated: 26/Oct/13

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

Type: Bug Priority: Major
Reporter: Pablo Santiago Sánchez Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony on all platforms (Windows, Linux and Mac)
Oracle 11g



 Description   

There's a bug on the DefaultQuoteStrategy when used with Oracle. The getColumnAlias created an invalid alias.

The name of the column had 31 chars, with _ being the 3rd. Column was 101 on the query. Resulting name of the alias started with _, which is invalid name for Oracle.

Example:
CO_SEQ_NOMEGIGANTEPRAKCTMEUDEUS

Alias formed was
_SEQ_NOMEGIGANTEPRAKCTMEUDEUS101

HOW TO FIX:
replace the regex on line 135:
original:
$columnName = preg_replace('/[^A-Za-z0-9_]/', '', $columnName);
fixed:
$columnName = preg_replace('/[^A-Za-z0-9]/', '', $columnName);



 Comments   
Comment by Rudi Uhrig Neto [ 16/Oct/13 ]

Hi there!

I would like to do a contribuition for this issue! I'm not safe with my sugestion, but someone can be helped!

I'm working with 2.4.0 Doctrine Version and I'm facing the same problem, "invalid character" due the function that make a cut off from the begining from alias.

My sugestion to solve this problem is maintain the separator '_' between alias name, but cutting off from the ending alias and reserv the lenght to the counter.

See bellow my modification code at DefaultQuoteStrategy::getColumnAlias() line 130, just replace all lines from function by these below:

DefaultQuoteStrategy.php
public function getColumnAlias($columnName, $counter, AbstractPlatform $platform, ClassMetadata $class = null)
{
    // 1 ) Trim the column alias to the maximum identifier length of the platform.
    //     If the alias is to long, characters are cut off from the ending subtracting the chars reserved to counter.
    // 2 ) Concatenate column name and counter
    // 3 ) Strip non alphanumeric characters
    // 4 ) Prefix with "_" if the result its numeric
    $columnName = substr($columnName, 0, $platform->getMaxIdentifierLength() - strlen($counter));
    $columnName = $columnName . $counter;
    $columnName = preg_replace('/[^A-Za-z0-9_]/', '', $columnName);
    $columnName = is_numeric($columnName) ? '_' . $columnName : $columnName;
      
    return $platform->getSQLResultCasing($columnName);
}

What do you guys think?

Comment by Pablo Santiago Sánchez [ 16/Oct/13 ]

Rudi, prefixing it with _ would keep the problem on Oracle. Since that name is for aliasing pourposes only, the _ char is useless.

I just remembered another possible situation: fields should not start with numbers!

Comment by Rudi Uhrig Neto [ 16/Oct/13 ]

Pablo,

The changes in my sugestion code don't consider the prefix '_', indepedent of the characteres in alias column name, the function will remove the last characteres from alias... see an example with column name DT_VERIFICACAO_SITUACAO_ACESSO.

The current code create a sql:
DT_VERIFICACAO_SITUACAO_ACESSO AS _VERIFICACAO_SITUACAO_ACESSO23,

My sugestion will produce:
DT_VERIFICACAO_SITUACAO_ACESSO AS DT_VERIFICACAO_SITUACAO_ACES23,

Comment by Pablo Santiago Sánchez [ 18/Oct/13 ]

Oh, sorry, my mistake. Your solution sounds better.

Since there's still no solution from the Doctrine Team, I'm iusing my own QuoteStrategy. Hope this bug gets fixed soon.

Comment by Benjamin Eberlei [ 26/Oct/13 ]

Fabio B. Silva Can you comment on Rudi Uhrig Neto solution? Its easily changed, but I am wondering if this is backwards compatible. I would want to merge the fix back to 2.3 and 2.4. Branch is ready to be committed for me locally.





[DDC-2744] Inheritance - Empty value for discriminatorColumn in query Created: 16/Oct/13  Updated: 16/Oct/13

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

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


 Description   

Hello, I have an inheritance problem with the following classes

<?php

namespace Proj\Bundle\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * ClassTop
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Proj\Bundle\MyBundle\Repository\ClassTopRepository")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="aVal", type="string")
 * @ORM\DiscriminatorMap({ "ValOne" = "ClassSubOne", "ValTwo" = "ClassSubTwo", "ValThree" = "ClassSubThree" })
 * 
 */
class ClassTop
{
    .....
}

class ClassSubOne extends ClassTop
{
    ....
}

class ClassSubTwo extends ClassTop
{
    ....
}

class ClassSubThree extends ClassTop
{
    ....
}

When i call findAll method my query is not correct

$entityManager->getRepository('ProjMyBundle:ClassSubOne')->findAll()

the query builded

SELECT field, field2 FROM CLASSTOP WHERE AVAL IN () 

The value for the discriminator column is not passed

Thanks for your help






[DDC-2742] 2 ManyToMany relations to the same target entity make the schema update fail by default Created: 15/Oct/13  Updated: 15/Oct/13

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

Type: Bug Priority: Major
Reporter: Christophe Coevoet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mapping, schematool


 Description   

At some point in the Doctrine releases (I don't remember which version it was), the default naming of the join table of a ManyToMany relation changed from using the property name to using the name of the target entity.

This makes it impossible to use multiple ManyToMany relations to the same target entity in a class without naming join tables explicitly. A SchemaException is thrown by the SchemaTool when trying to update the schema.

Note that this issue is not caught by the SchemaValidator. It will display us that the mapping files are correct (before throwing the above exception in the second step when trying to compare it to the existing database)






pager produces wrong results on postgresql (DDC-1958)

[DDC-2729] Same bug affects SQLServer2008Platform Created: 07/Oct/13  Updated: 07/Oct/13

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

Type: Sub-task Priority: Major
Reporter: Rafi Adnan Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: paginator
Environment:

SQL Server 10.50.1617
unixODBC 2.2.14
PHP 5.4.19



 Description   

If the class is patched with the following:

if ($this->platform instanceof SQLServer2008Platform)

{ $this->preserveSqlOrdering($AST, $sqlIdentifier, $innerSql, $sql); }

It fixes the issue.






[DDC-2746] When generating DQL query entities with "Class Table Inheritance" is a SQL generated inconsistent Created: 16/Oct/13  Updated: 18/Oct/13

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

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

Attachments: File DDC2746Test.php     File DDC2746Test_original.php    

 Description   

When I run the query DQL involving entities "Class Table Inheritance" is a SQL generated inconsistent see this gist: https://gist.github.com/hugohenrique/b322e8d998c870265177



 Comments   
Comment by Hugo Henrique [ 17/Oct/13 ]

An example of incoherent generation of SQL:
https://gist.github.com/hugohenrique/b322e8d998c870265177





[DDC-2727] "Expression" or "Update" API, similar to the Criteria API Created: 07/Oct/13  Updated: 07/Oct/13

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: Matthieu Napoli Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I created a discussion in the mailing list (https://groups.google.com/forum/#!topic/doctrine-dev/7HfEqOwhkDk) but no answer, so I'm moving the discussion here.


The Criteria API provides an abstraction to filter collections/repositories, may they be in memory (filtering in PHP) or in a database (filtering using a SQL query).

I was thinking about an "Expression" API which would work like array_map to apply changes in bulk to entities.

For example, if you have a collection where entities have a $position field, if I insert an item in the list, I have to increment the position of all the following items. For this, I have 2 options:

  • PHP: loading the entities in memory, iterate over them and increment $position
  • SQL: run a UPDATE position=position + 1 WHERE …

The second option is much more efficient, but it breaks the abstraction of the model because I have some behavior written explicitely in SQL. Furthermore, the objects loaded in memory will note be updated with the SQL query.

So the "Expression" API would work like the Criteria API:

interface Updatable {
    public function apply(Expression $e);
}

$expression = new Expression();

// For each item after position "10"
$expression->criteria->where(Criteria::expr()->gt('position', 10));
// Increment the position
$expression->set('position', 'position + 1');

$collection->map($expression);

The expression here would be applied:

  • in memory if the collection is already loaded
  • else in database using SQL

The expression could be applied to a Collection and to a Repository (like the Criteria).


About the API offered by the Expression class, there are several options:

// Option 1
// More powerful, but needs to parse and evaluate the string
class Expression
{
    public $criteria;
    public function set($field, $value);
}
 
$expression->set('position', 'position + 1');
 
// Option 2
// Easier to implement, more limited
class Expression
{
    public $criteria;
    public function setValue($field, $value);
    public function setValueFromField($targetField, $sourceField);
    public function add($field, $number);
    public function multiply($field, $number);
    public function divide($field, $number);
}
 
// Option 3
// Like option 2 but more extensible
class Expression
{
    public $criteria;
    public function set($field, Operation $operation);
}

I think I like the third one better because we have full control over the supported operations, and adding support to new kinds of operation is easy. The first one would require defining a whole language of allowed expressions...


What do you think of all that?



 Comments   
Comment by Matthieu Napoli [ 07/Oct/13 ]

Added option 3 after trying to write a POC

Comment by Matthieu Napoli [ 07/Oct/13 ]

Here is a POC on the doctrine/collections side: https://github.com/mnapoli/collections/compare/master...feature;Updatable works with ArrayCollection

I'm looking at the ORM side.

Feedback welcome, especially with the class/namespace/method names.





[DDC-2726] EventSubscriber PreUpdate Error Bug? Created: 06/Oct/13  Updated: 17/Oct/13

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: Nelson Ford Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm


 Description   

Should this:

public function preUpdate(PreUpdateEventArgs $eventArgs)
{
    $entity = $eventArgs->getEntity();
    $em = $eventArgs->getEntityManager();
    $uow = $em->getUnitOfWork();

    if ($entity instanceof User) {
        if ($eventArgs->hasChangedField('finalStatus')) {
            $entity->setFinalStatusDate(new \DateTime('now'));
            $uow->recomputeSingleEntityChangeSet(
                $em->getClassMetadata("MyAdminBundle:User"),
                $entity
            );
        }
        if ($eventArgs->hasChangedField('membershipCode')) {
            $entity->setMembershipCodeDate(new \DateTime('now'));
            $uow->recomputeSingleEntityChangeSet(
                $em->getClassMetadata("MyAdminBundle:User"),
                $entity
            );
        }
    }
}

...result in this?

Catchable Fatal Error: Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs::__construct() must be an array, null given, called in /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 995 and defined in /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php line 47

I'm just setting a time stamp for two updated values. Dumping the 3rd argument in PreUpdateEventArgs.php on line 47 reveals an array of changes. I'm not sure if this is a bug or if I'm performing this simple operation incorrectly.



 Comments   
Comment by Marco Pivetta [ 17/Oct/13 ]

Can you write an integration test around it? Looks like the changeset is removed in a particular edge case, but it's hard to figure it out without a test.





[DDC-2709] Defining Columns as "Updatable" or "Insertable" Created: 27/Sep/13  Updated: 27/Sep/13

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: Martin Prebio Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

With Hibernate I can define a column as Updatable/Insertable or non-Updatable/non-Insertable so that this field is considered read-only and is not part of any update/insert statement. I'd like to have the same possibility in Doctrine.

In my use case a value is generated and maintained by database triggers. In my application I only want to read this value but the application should never try to insert or update the column.

Updatable/Insertable in the Hibernate documentation: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping-property-column






[DDC-2704] When using Discriminator EntityManager#merge fails Created: 25/Sep/13  Updated: 25/Sep/13

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: Vladyslav Petrovych Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I have the following hierarchy:

  • AgentConfig has relation ManyToOne with AgentTask.
  • AgentTask has DiscriminatorColumn & DiscriminatorMap assigned to it.
  • AgentTask has relation ManyToOne with AgentTaskConfig.

I believe the problem is because of the following:

UnitOfWork#doMerge has the tries to get properties the following way:

// Merge state of $entity into existing (managed) entity
foreach ($class->reflClass->getProperties() as $prop) {

This obviously doesn't get the parent class (AgentTask) properties.

Later on UnitOfWork fails on line:

$prevClass->reflFields[$assocField]->getValue($prevManagedCopy)->add($managedCopy);

because $prevManagedCopy doesn't have properties set from entity.

My proposal is to get the properties the following way:

$properties = $class->reflClass->getProperties();
$parent = $class->reflClass;
while (($parent = $parent->getParentClass()) != null) {
    $properties = array_merge($parent->getProperties(), $properties);
}

// Merge state of $entity into existing (managed) entity
foreach ($properties as $prop) {





[DDC-2691] Test Suite: Drop other connections before dropping database PostgreSQL Created: 19/Sep/13  Updated: 19/Sep/13

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

Type: Improvement Priority: Major
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 Professional 64 bits
PHP 5.4.11 (cli) (built: Jan 16 2013 20:26:26)
Doctrine dev-master from 18-9-2013
PostgreSQL 9.2.4 build 1600, 64-bits



 Description   

The test suite is trying to run the command

DROP DATABASE doctrine_tests

This fails, together with lots of tests when another user is connected (for example through the pgAdmin program). It would be nice if the test suite had an option to drop existing connections, which can be done with the following command:

SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'doctrine_tests';





[DDC-2690] Doctrine ORM test suite failing on PostgresSQL Created: 19/Sep/13  Updated: 01/Oct/13

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: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 Professional 64 bits
PHP 5.4.11 (cli) (built: Jan 16 2013 20:26:26)
Doctrine dev-master from 18-9-2013
PostgreSQL 9.2.4 build 1600, 64-bits
Commit for doctrine/common d9dea98243c733ff589aab10e321de4f14a63ab4



 Description   

This issue is related to: http://www.doctrine-project.org/jira/browse/DDC-2689

PHPUnit 3.7.27 by Sebastian Bergmann.

Configuration read from C:\inetpub\symfony23\vendor\doctrine\orm\postgres.phpunit.xml

......................SSSSSS.................................   61 / 2074 (  2%)
.............................................................  122 / 2074 (  5%)
.....................................................S.......  183 / 2074 (  8%)
.............................................................  244 / 2074 ( 11%)
.............................................................  305 / 2074 ( 14%)
.............................................................  366 / 2074 ( 17%)
.............................................................  427 / 2074 ( 20%)
.............................................E...............  488 / 2074 ( 23%)
.............................................................  549 / 2074 ( 26%)
.............................................................  610 / 2074 ( 29%)
..SSSS..................................................S....  671 / 2074 ( 32%)
.............................................................  732 / 2074 ( 35%)
...........................S................................S  793 / 2074 ( 38%)
.............................................................  854 / 2074 ( 41%)
.....S..SS.................................S.................  915 / 2074 ( 44%)
.............................................................  976 / 2074 ( 47%)
............................................................. 1037 / 2074 ( 50%)
............................................................. 1098 / 2074 ( 52%)
............................................................. 1159 / 2074 ( 55%)
.................................................S........... 1220 / 2074 ( 58%)
..................................S.......................... 1281 / 2074 ( 61%)
............................................................. 1342 / 2074 ( 64%)
............................................................. 1403 / 2074 ( 67%)
............................................................. 1464 / 2074 ( 70%)
............................................................. 1525 / 2074 ( 73%)
............................................................. 1586 / 2074 ( 76%)
............................................................. 1647 / 2074 ( 79%)
............................................................. 1708 / 2074 ( 82%)
............................................................. 1769 / 2074 ( 85%)
............................................................. 1830 / 2074 ( 88%)
............................................................. 1891 / 2074 ( 91%)
...................................................S......... 1952 / 2074 ( 94%)
....S...............................S........................ 2013 / 2074 ( 97%)
..................................

Time: 42.33 seconds, Memory: 83.50Mb

There was 1 error:

1) Doctrine\Tests\ORM\Functional\ProxiesLikeEntitiesTest::testPersistUpdate
Exception: [Doctrine\Common\Proxy\Exception\OutOfBoundsException] Missing value for primary key id on Doctrine\Tests\Models\CMS\CmsUser

With queries:
7. SQL: '"COMMIT"' Params: 
6. SQL: 'INSERT INTO cms_users (id, status, username, name, email_id) VALUES (?, ?, ?, ?, ?)' Params: '385', '', 'ocramius', 'Marco', ''
5. SQL: '"START TRANSACTION"' Params: 
4. SQL: 'SELECT NEXTVAL('cms_users_id_seq')' Params: 
3. SQL: 'CREATE TABLE cms_users (id INT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))' Params: 
2. SQL: 'SHOW search_path' Params: 

Trace:
C:\inetpub\symfony23\vendor\doctrine\common\lib\Doctrine\Common\Proxy\AbstractProxyFactory.php:125
C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\ProxiesLikeEntitiesTest.php:51
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:983
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:838
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestResult.php:648
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:783
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:775
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:745
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:705
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\TestRunner.php:349
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\Command.php:176
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\Command.php:129
C:\inetpub\symfony23\vendor\phpunit\phpunit\phpunit.php:46


C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\OrmFunctionalTestCase.php:477
C:\inetpub\symfony23\vendor\doctrine\common\lib\Doctrine\Common\Proxy\AbstractProxyFactory.php:125
C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\ProxiesLikeEntitiesTest.php:51

Caused by
Doctrine\Common\Proxy\Exception\OutOfBoundsException: Missing value for primary key id on Doctrine\Tests\Models\CMS\CmsUser

C:\inetpub\symfony23\vendor\doctrine\common\lib\Doctrine\Common\Proxy\Exception\OutOfBoundsException.php:41
C:\inetpub\symfony23\vendor\doctrine\common\lib\Doctrine\Common\Proxy\AbstractProxyFactory.php:125
C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\ProxiesLikeEntitiesTest.php:51

FAILURES!
Tests: 2047, Assertions: 7055, Errors: 1, Skipped: 23.



 Comments   
Comment by Flip [ 30/Sep/13 ]

How can this possibly pass on the travis-ci builds ?? Maybe this is an indication that something is wrong with the travis setup.

This is the setup/input: https://github.com/doctrine/doctrine2/blob/master/tests/Doctrine/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php#L51

This is where execution fails: https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php#L125

Comment by Flip [ 01/Oct/13 ]

This is a related PR https://github.com/doctrine/common/pull/298





[DDC-2689] Doctrine ORM test suite failing on MySQL Created: 19/Sep/13  Updated: 30/Sep/13

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: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 Professional 64 bits
PHP 5.4.11 (cli) (built: Jan 16 2013 20:26:26)
Doctrine dev-master from 18-9-2013
mysql-5.6.13-winx64
Commit for doctrine/common d9dea98243c733ff589aab10e321de4f14a63ab4



 Description   

This issue is related to http://www.doctrine-project.org/jira/browse/DDC-2690

PHPUnit 3.7.27 by Sebastian Bergmann.

Configuration read from C:\inetpub\symfony23\vendor\doctrine\orm\mysql.phpunit.xml

......................SSSSSS.................................   61 / 2074 (  2%)
.............................................................  122 / 2074 (  5%)
.....................................................S.......  183 / 2074 (  8%)
.............................................................  244 / 2074 ( 11%)
.............................................................  305 / 2074 ( 14%)
.............................................................  366 / 2074 ( 17%)
.............................................................  427 / 2074 ( 20%)
............................................SE...............  488 / 2074 ( 23%)
.............................................................  549 / 2074 ( 26%)
.............................................................  610 / 2074 ( 29%)
......SSSSSS.............S..............................S...S  671 / 2074 ( 32%)
...........S..............................S................E.  732 / 2074 ( 35%)
...........................S.................................  793 / 2074 ( 38%)
.............................................................  854 / 2074 ( 41%)
.....S..SS...................................................  915 / 2074 ( 44%)
.............................................................  976 / 2074 ( 47%)
............................................................. 1037 / 2074 ( 50%)
............................................................. 1098 / 2074 ( 52%)
............................................................. 1159 / 2074 ( 55%)
.................................................S........... 1220 / 2074 ( 58%)
..................................S.......................... 1281 / 2074 ( 61%)
............................................................. 1342 / 2074 ( 64%)
............................................................. 1403 / 2074 ( 67%)
............................................................. 1464 / 2074 ( 70%)
............................................................. 1525 / 2074 ( 73%)
............................................................. 1586 / 2074 ( 76%)
............................................................. 1647 / 2074 ( 79%)
............................................................. 1708 / 2074 ( 82%)
............................................................. 1769 / 2074 ( 85%)
............................................................. 1830 / 2074 ( 88%)
............................................................. 1891 / 2074 ( 91%)
...................................................S......... 1952 / 2074 ( 94%)
....S...............................S........................ 2013 / 2074 ( 97%)
..................................

Time: 39.42 seconds, Memory: 79.50Mb

There were 2 errors:

1) Doctrine\Tests\ORM\Functional\ProxiesLikeEntitiesTest::testPersistUpdate
Exception: [Doctrine\Common\Proxy\Exception\OutOfBoundsException] Missing value for primary key id on Doctrine\Tests\Models\CMS\CmsUser

With queries:
5. SQL: '"COMMIT"' Params: 
4. SQL: 'INSERT INTO cms_users (status, username, name, email_id) VALUES (?, ?, ?, ?)' Params: '', 'ocramius', 'Marco', ''
3. SQL: '"START TRANSACTION"' Params: 
2. SQL: 'CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB' Params: 

Trace:
C:\inetpub\symfony23\vendor\doctrine\common\lib\Doctrine\Common\Proxy\AbstractProxyFactory.php:125
C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\ProxiesLikeEntitiesTest.php:51
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:983
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:838
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestResult.php:648
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:783
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:775
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:745
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:705
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\TestRunner.php:349
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\Command.php:176
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\Command.php:129
C:\inetpub\symfony23\vendor\phpunit\phpunit\phpunit.php:46


C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\OrmFunctionalTestCase.php:477
C:\inetpub\symfony23\vendor\doctrine\common\lib\Doctrine\Common\Proxy\AbstractProxyFactory.php:125
C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\ProxiesLikeEntitiesTest.php:51

Caused by
Doctrine\Common\Proxy\Exception\OutOfBoundsException: Missing value for primary key id on Doctrine\Tests\Models\CMS\CmsUser

C:\inetpub\symfony23\vendor\doctrine\common\lib\Doctrine\Common\Proxy\Exception\OutOfBoundsException.php:41
C:\inetpub\symfony23\vendor\doctrine\common\lib\Doctrine\Common\Proxy\AbstractProxyFactory.php:125
C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\ProxiesLikeEntitiesTest.php:51

2) Doctrine\Tests\ORM\Functional\Ticket\DDC1514Test::testIssue
Exception: [PHPUnit_Framework_Error_Notice] Trying to get property of non-object

With queries:
14. SQL: '"COMMIT"' Params: 
13. SQL: 'INSERT INTO DDC1514EntityB (entityAFrom_id, entityATo_id) VALUES (?, ?)' Params: '2', '1'
12. SQL: 'INSERT INTO DDC1514EntityB (entityAFrom_id, entityATo_id) VALUES (?, ?)' Params: '1', '2'
11. SQL: 'INSERT INTO DDC1514EntityA (title, entityC_id) VALUES (?, ?)' Params: 'bar', '1'
10. SQL: 'INSERT INTO DDC1514EntityA (title, entityC_id) VALUES (?, ?)' Params: 'foo', ''
9. SQL: 'INSERT INTO DDC1514EntityC (title) VALUES (?)' Params: 'baz'
8. SQL: '"START TRANSACTION"' Params: 
7. SQL: 'ALTER TABLE DDC1514EntityB ADD CONSTRAINT FK_B7F2235B64DC3373 FOREIGN KEY (entityATo_id) REFERENCES DDC1514EntityA (id)' Params: 
6. SQL: 'ALTER TABLE DDC1514EntityB ADD CONSTRAINT FK_B7F2235B4D8FF1AD FOREIGN KEY (entityAFrom_id) REFERENCES DDC1514EntityA (id)' Params: 
5. SQL: 'ALTER TABLE DDC1514EntityA ADD CONSTRAINT FK_2EFB72E12014DB0 FOREIGN KEY (entityC_id) REFERENCES DDC1514EntityC (id)' Params: 
4. SQL: 'CREATE TABLE DDC1514EntityC (id INT AUTO_INCREMENT NOT NULL, title VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB' Params: 
3. SQL: 'CREATE TABLE DDC1514EntityB (id INT AUTO_INCREMENT NOT NULL, entityAFrom_id INT DEFAULT NULL, entityATo_id INT DEFAULT NULL, INDEX IDX_B7F2235B4D8FF1AD (entityAFrom_id), INDEX IDX_B7F2235B64DC3373 (entityATo_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB' Params: 
2. SQL: 'CREATE TABLE DDC1514EntityA (id INT AUTO_INCREMENT NOT NULL, title VARCHAR(255) NOT NULL, entityC_id INT DEFAULT NULL, INDEX IDX_2EFB72E12014DB0 (entityC_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB' Params: 

Trace:
C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\Ticket\DDC1514Test.php:60
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:983
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:838
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestResult.php:648
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php:783
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:775
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:745
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php:705
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\TestRunner.php:349
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\Command.php:176
C:\inetpub\symfony23\vendor\phpunit\phpunit\PHPUnit\TextUI\Command.php:129
C:\inetpub\symfony23\vendor\phpunit\phpunit\phpunit.php:46


C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\OrmFunctionalTestCase.php:477
C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\Ticket\DDC1514Test.php:60

Caused by
Trying to get property of non-object

C:\inetpub\symfony23\vendor\doctrine\orm\tests\Doctrine\Tests\ORM\Functional\Ticket\DDC1514Test.php:60

FAILURES!
Tests: 2047, Assertions: 7035, Errors: 2, Skipped: 28.



 Comments   
Comment by Flip [ 30/Sep/13 ]

First error is the same as this one: http://www.doctrine-project.org/jira/browse/DDC-2690#comment-21186

Second error has a bugfix here: https://github.com/doctrine/doctrine2/pull/805





[DDC-2701] Collections in originalEntityData gets over written Created: 23/Sep/13  Updated: 23/Sep/13

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

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


 Description   

I was trying to use the UnitOfWork::getOriginalEntityData method and i noticed that if there is a collection in that object, it changes in the uow original datas when i change it on my original object

In my case the collection is ManyToMany unidirectional

I think this happens because both the uow and the object work with the same reference to the collection
maybe adding a clone of the collection instead of the real one, i don't know if it is possible

Thank you for taking a look and for Doctrine!

Tom






[DDC-2697] ObjectHydrator::hydrateRowData fails to hydrate first fetch joined entity Created: 20/Sep/13  Updated: 06/Dec/13

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

Type: Bug Priority: Major
Reporter: Austin Morris Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

All



 Description   

Let's say I have accounts, contacts, and contact types. Any given contact can have be any kind of contact type to any account. This is all managed through an account_contacts table with a 3-way composite PK of the contact_id, account_id, and type_id.

All of this translates to 4 entities, the account, contact, type, and accountContact entity. The id of the accountContact entity is the three other entities which is holds.

When I use query builder to retrieve the accountContacts based on some condition, and also fetch join contacts, accounts, and types so that they are eagerly loaded, the ObjectHydrator fails to load the first accountContact returned.

This is because the first time through hydrateRowData, the fetch joined entities are hydrated first. The problem is $this->_rsm->parentAliasMap[$dqlAlias] does not contain an entry for the accountContact (root entity). Not until an accountContact is hydrated does that get set. In the mean time, the other three entities were set to null because there is no parent alias yet (in version 2.4, this is line 405.

Subsequent loops through hydrateRowData work because by this time the parent alias is set. But that first row returned is always an accountContact containing three null objects.



 Comments   
Comment by Benjamin Eberlei [ 26/Oct/13 ]

Austin Morris Can you show the QueryBuilder select clause you are using? Have you tried sorting the accountContacts first?

$qb->select('accountContacts, contact, account, type')

This way it should definately work, and then there is also some attempts to resort this way if you dont have that, but its not always working.

Comment by Austin Morris [ 06/Dec/13 ]

Sorry, I don't have the original select clause. I ended up doing something different and can't seem to find my original code.

Comment by Benjamin Eberlei [ 06/Dec/13 ]

I have another person that reported a simliiar bug with reproducable test case. I hope to investigate this very soon.





[DDC-2695] Order by clause left in subquery when using MSSQL and Paginator Created: 20/Sep/13  Updated: 20/Sep/13

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: Paul Mansell Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows, Microsoft SQL Server



 Description   

When using the Doctrine paginator and Fetch Join Collections = true and when the original query has an "ORDER BY" clause in it - the subquery created is something like "SELECT DISTINCT FROM (.... ORDER BY ....) as dctrn_result" - when using Microsoft SQL server having the "ORDER BY" clause in a subquery throws an error. This is a similar problem to http://doctrine-project.org/jira/browse/DDC-2282 but that was for the Count Walker - this is for the LimitSubqueryOutputWalker. The fix is the same.



 Comments   
Comment by Paul Mansell [ 20/Sep/13 ]

Problem still occurs in 2.4 - but different error message,

Query :

SELECT * FROM (SELECT DISTINCT id0, ROW_NUMBER() OVER (ORDER BY c1_.iccid ASC) AS doctrine_rownum FROM (SELECT w0_.id AS id0, w0_.batch_id AS batch_id1, c1_.id AS id2, c1_.iccid AS iccid3, c2_.id AS id4, c2_.msisdn AS msisdn5, c3_.id AS id6, c3_.name AS name7, c4_.id AS id8, c5_.id AS id9, c5_.name AS name10, w6_.id AS id11, w6_.created AS created12, w7_.id AS id13, w7_.ident AS ident14, w8_.id AS id15, w8_.ident AS ident16, c9_.id AS id17, c10_.id AS id18, c10_.contract_length AS contract_length19, c10_.rental AS rental20, w11_.id AS id21, w11_.ident AS ident22 FROM workflow_request w0_ WITH (NOLOCK) INNER JOIN core_sim c1_ ON w0_.sim = c1_.id LEFT JOIN core_connection c2_ ON c1_.active_connection_id = c2_.id INNER JOIN core_billing_account c3_ ON c1_.billing_account_id = c3_.id INNER JOIN core_mno_account c4_ ON c1_.mno_account_id = c4_.id INNER JOIN core_mno c5_ ON c4_.mno_id = c5_.id INNER JOIN workflow_request_log w6_ ON w0_.id = w6_.request INNER JOIN workflow_action w7_ ON w0_.action = w7_.id INNER JOIN workflow_request_status w8_ ON w0_.status = w8_.id INNER JOIN core_customer_solution c9_ ON w0_.customer_solution = c9_.id INNER JOIN core_customer_tariff c10_ ON c9_.customer_tariff_id = c10_.id INNER JOIN workflow_request_action w11_ ON w6_.request_action = w11_.id WHERE w7_.ident IN AND w8_.ident = ? AND w11_.ident = ?) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 25' with params ["activate", "network", "approved"]

Error :

SQLSTATE[42000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]The multi-part identifier "c1_.iccid" could not be bound.





[DDC-2694] Hydrating with entities with the NEW operator Created: 19/Sep/13  Updated: 21/Jan/14

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

Type: New Feature Priority: Major
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 3
Labels: None

Issue Links:
Duplicate
is duplicated by DDC-2899 Allow the NEW operator to construct o... Resolved

 Description   

It would be nice if the new function accepted objects as parameters, like this:

new Country(country, some_extra_stuff)

Alternatively another keyword could be introduced that constructs the object with the parameter and afterwards hydrates it.






[DDC-2675] WITH (NOLOCK) failing when using JOIN Created: 12/Sep/13  Updated: 31/Jan/14

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

Type: Bug Priority: Major
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: None
Environment:

MSSQL 2008 R2


Issue Links:
Duplicate
is duplicated by DDC-2310 Recent changes to DBAL SQL Server pla... Resolved
Reference
is referenced by DDC-2919 LockMode::NONE evaluation inconsisten... Resolved

 Description   

I ran the doctrine test suite and there are a lot of tests failing with

[SQL Server]Incorrect syntax near the keyword 'with'

List of failing test because of this issue:
2) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testUnnamedScalarResultsAreOneBased
3) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testOrderByResultVariableCollectionSize
4) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testIsNullAssociation
5) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testSelectSubselect
6) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testInSubselect
7) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testGroupByMultipleFields
8) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testUpdateAs
9) Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest::testDeleteAs
10) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testCRUD
11) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testSelfReferencingOneToOne
12) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testSelfReferencingManyToMany
13) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testLazyLoading2
14) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testBulkUpdateIssueDDC368
15) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testBulkUpdateNonScalarParameterDDC1341
16) Doctrine\Tests\ORM\Functional\ClassTableInheritanceTest::testQueryForInheritedSingleValuedAssociation
17) Doctrine\Tests\ORM\Functional\Locking\OptimisticTest::testJoinedChildFailureThrowsException
18) Doctrine\Tests\ORM\Functional\Locking\OptimisticTest::testJoinedParentFailureThrowsException
19) Doctrine\Tests\ORM\Functional\OrderedJoinedTableInheritanceCollectionTest::testOrderdOneToManyCollection
20) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateSum
21) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateAvg
22) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateMin
23) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateMax
24) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testAggregateCount
25) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionAbs
26) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionConcat
27) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionLength
28) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionLocate
29) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionLower
30) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionMod
31) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionSqrt
32) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionUpper
33) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionSubstring
34) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testFunctionTrim
35) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testOperatorAdd
36) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testOperatorSub
37) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testOperatorMultiply
38) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testOperatorDiv
39) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testConcatFunction
40) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testDateDiff
41) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testDateAdd
42) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testDateSub
43) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testBitOrComparison
44) Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest::testBitAndComparison
45) Doctrine\Tests\ORM\Functional\SQLFilterTest::testJoinSubclassPersister_FilterOnlyOnRootTableWhenFetchingSubEntity
46) Doctrine\Tests\ORM\Functional\SQLFilterTest::testJoinSubclassPersister_FilterOnlyOnRootTableWhenFetchingRootEntity
47) Doctrine\Tests\ORM\Functional\Ticket\DDC163Test::testQueryWithOrConditionUsingTwoRelationOnSameEntity
48) Doctrine\Tests\ORM\Functional\Ticket\DDC168Test::testJoinedSubclassPersisterRequiresSpecificOrderOfMetadataReflFieldsArray
49) Doctrine\Tests\ORM\Functional\Ticket\DDC1995Test::testIssue
50) Doctrine\Tests\ORM\Functional\Ticket\DDC1995Test::testQueryCache
51) Doctrine\Tests\ORM\Functional\Ticket\DDC2090Test::testIssue
53) Doctrine\Tests\ORM\Functional\Ticket\DDC279Test::testDDC279
54) Doctrine\Tests\ORM\Functional\Ticket\DDC933Test::testLockCTIClass

One example, test 20)
Generated SQL:

SELECT SUM(c0_.salary) AS sclr0
FROM company_managers c1_
INNER JOIN company_employees c0_ ON c1_.id = c0_.id
INNER JOIN company_persons c2_ ON c1_.id = c2_.id
WITH (NOLOCK)

Solution:
Placing WITH (NOLOCK) after the table(s), instead of after ON clause. Depending on the wanted result it should be placed several times when using JOIN. See this StackOverflow Post for more information:
http://stackoverflow.com/questions/3783525/sql-server-nolock-and-joins



 Comments   
Comment by Steve Müller [ 15/Jan/14 ]

Please refer to DDC-2310 as it describes exactly the same issue.

Comment by Doctrine Bot [ 31/Jan/14 ]

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





[DDC-2672] Using fetchAll() in Hydration can improve TCP Wait Created: 11/Sep/13  Updated: 13/Dec/13

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: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hydration currently fetches the rows and hydrates them by interleaving both operations. This can cause an increased TCP wait time, because the PHP processing takes a bit of time.

We should investigate weather changing to fetchAll() improves the overall performance.

Ping Thomas RabaixGuilherme Blanco



 Comments   
Comment by Benjamin Eberlei [ 13/Dec/13 ]

We can introduce a new query hint to allow us to support both: 'DBAL_FETCH_ALL'. If that is set, use fetchAll(), otherwise fetchRow().





[DDC-2659] Notice: Undefined index: sourceToTargetKeyColumns in /doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister .php line 1180 Created: 08/Sep/13  Updated: 08/Sep/13

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: Taylor Kaplan Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

Symfony2 With PHP 5.5 on Ubuntu 12.04 LTS using Apache 2


Attachments: File Client.php     File ClientFixtures.php     File User.php     File UserFixtures.php    

 Description   

I am getting this error:

 Notice: Undefined index: sourceToTargetKeyColumns

When I try to load my data fixture. There are two ordered fixtures that I'm dealing with: Clients and Users. The client datafixture looks like:

    	/**
    	 * {@inheritDoc}
    	 */
    	 public function load(ObjectManager $manager)
    	 {
    
    		for($index = 0; $index < 224; $index ++)
    		{
    			$client = new Client();
    			$manager->persist($client);
                        $this->addReference($index . 'Client', $client);
    		}
    
    		$manager->flush();
    		$manager->clear();
    	 }
    
    	 public function getOrder()
    	 {
    	 	return 0;
    	 }

While the user data fixture looks like:

     $user = New User();
     $client = $this->getReference($index . 'Client');

     // This line is causing the problem
     $client->setUser($user);

For whatever reason, I don't seem to be having issues with any of my other fixtures. Just this one. I've doubled check the entity relationships which are shown bellow.

My Client.php entity:

    /**
     * @ORM\ OneToOne(targetEntity="User", mappedBy="clientAccount")
     */
    protected $user;

My User.php entity:

    /**
     * @ORM\ OneToOne(targetEntity="Client", inversedBy="user")
     */
    protected $clientAccount;

There seems to be a bug with the return value of getAssociationMapping() for special conditions when implemented in BasicEntityPersister. The files for my fixtures and entities for this project have been attached.






[DDC-2671] YAML mapping: entity generation with inheritance does work Created: 11/Sep/13  Updated: 11/Sep/13

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

Type: Bug Priority: Major
Reporter: Peter Tulala Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance, mapping, yaml


 Description   

Entities inherited from parent entities should be defined as class Foo extends Bar. However YAML driver ignores inheritance hierarchy and does not use "extends" keyword at all.






[DDC-2649] Hydration in bidirectional, OneToOne relationship, PK as FK for owning side, is problematic Created: 04/Sep/13  Updated: 04/Sep/13

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

Type: Bug Priority: Major
Reporter: Jérôme Viveret Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: FK, OneToOne, PK, bidirectional


 Description   

I am referring to this situation https://gist.github.com/anonymous/6435032

The following problem occur:

When using HardCover as the root entity of a query, the ObjectHydrator fails to properly register the first [HardCover of the resultset]'s Book. Only the first. The following HardCover have their Books correctly linked. The inverse situation (using Book as the root entity) works fine.

When some other entity (say WoodenPart) is linked to HardCover via a ManyToOne association, using WoodenPart as a query root results in no WoodenPart have their HardCover registered.






[DDC-2642] GROUP BY with inherited entity (which is also in SELECT clause) does not list columns from inheriting entities Created: 30/Aug/13  Updated: 30/Aug/13

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

Type: Bug Priority: Major
Reporter: Ondřej Mirtes Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PostgreSQL



 Description   

The summary pretty much sums it up.

Code example: https://gist.github.com/ondrejmirtes/6388434






[DDC-2637] [GH-769] Add Custom Persisters Created: 28/Aug/13  Updated: 15/Apr/14

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: Doctrine Bot Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by DDC-2629 [GH-768] DDC-391: Add support to conf... Resolved
Reference
relates to DDC-391 Allow to specifiy custom Entity and C... In Progress

 Description   

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

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

Message:

Adding support for custom persisters as defined by DDC-391.
Implementing both Entity and Collection based Persisters



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

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

Comment by Doctrine Bot [ 15/Apr/14 ]

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





[DDC-2636] Handle SQLite with dot notation in @Table and @JoinTable Created: 27/Aug/13  Updated: 20/Dec/13

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: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: None


 Description   

When using SQLite and having dot notation in @Table or @JoinTable this is already handled in DBAL Schema and transformed to __. However it is not handled in ORM tables, so it breaks.



 Comments   
Comment by Michaël Perrin [ 20/Dec/13 ]

I opened a PR to solve this issue: https://github.com/doctrine/doctrine2/pull/881
This PR also adds better schema support.

If there are things I did the wrong way, any comment is welcome.





[DDC-2635] Problems with Filtering SQL Queries based on schema Created: 27/Aug/13  Updated: 27/Aug/13

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: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The filtering in Schema Tool based on current database schema is not extendable very easily. We need a way to allow creating all, or only a subset of schemas in both supporting and non supporting databases.






[DDC-2631] Replacing object in a OneToOne with OrphanRemoval=true isn't working as expected Created: 23/Aug/13  Updated: 26/Nov/13

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

Type: Bug Priority: Major
Reporter: Felipe Guaycuru Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

PHP 5.4



 Description   

So I have a class defined like this:

class PhoneSettings {
[...]

/**

  • @OneToOne(targetEntity="Medium", cascade= {"persist", "remove"}

    , orphanRemoval=true)

  • @JoinColumn(name="medium_id", referencedColumnName="medium_id", nullable=true, onDelete="SET NULL")
    **/
    protected $medium = null;

[...]
}
And class Medium has no reference to the class Settings.

Now suppose I have a $Settings object that is already persisted and has been correctly loaded. Also suppose that the $Settings object has a $medium (that is, $Settings->medium = $OldMedium)

Now suppose I do:

$Settings->medium = $NewMedium;
Where $NewMedium is a different Medium object.

When I persist $Settings, Doctrine does delete $OldMedium from the DB, but the problem is that it also deletes $NewMedium ...

I have tried removing onDelete="SET NULL", but then I receive a "cannot delete, constraint failed" error...






[DDC-2630] Filters with joined inheritance Created: 22/Aug/13  Updated: 09/Jan/14

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: Florian Vilpoix Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance, sql-walker, sqlfilter


 Description   

Hello,

I'm trying to use SQLFilter with a Joined Inheritance, and the sql Walker never applies filters on the sub-class, even if I make my SELECT on the sub-class or the root.

In the SqlWalker, the methods 'generateFilterConditionSQL' says :

// The classes in the inheritance will be added to the query one by one,
// but only the root node is getting filtered

I don't understand why, and I would like to know if there is any way to apply filters to subclasses in joined-inheritance.

Thanks a lot



 Comments   
Comment by Menno Holtkamp [ 09/Jan/14 ]

Are you sure you apply the filter on the root Entity? This discussion might be usefull:
https://groups.google.com/forum/#!topic/doctrine-user/e1cPZOorfaQ





[DDC-2617] OneToMany annotation should not work with MappedSuperclass Created: 18/Aug/13  Updated: 08/Sep/13

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

Type: Bug Priority: Major
Reporter: jonathan bensaid Assignee: Fabio B. Silva
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Using annotations in my model mapped to "mapped superclass" I can use one to many relations et every bidirectional relation I want.
Using yaml or xml it suddenly doesn't work and throw me an error. Annotations should work the same way and should not authorize one to many or any bidirectional relation.



 Comments   
Comment by Benjamin Eberlei [ 08/Sep/13 ]

Its actually the other way around, yml and xml need to allow this, because it works with association overrides.

Comment by Benjamin Eberlei [ 08/Sep/13 ]

Assigning Fabio





[DDC-2605] Console command generates entity stubs that break type hinting contracts. Created: 09/Aug/13  Updated: 12/Aug/13

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

Type: Bug Priority: Major
Reporter: Alex Parker Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: cli, orm, stubs, tools, type-hinting
Environment:

Debian Linux (crunchbang)
PHP 5.4.4-14+deb7u2 (cli)
MySQL Server version: 5.5.31-0+wheezy1 (Debian)


Attachments: PNG File thcontract.png    

 Description   

I've found that the doctrine cli tool seems to break PHP's type hinting contracts in the scenario outlined in the attached diagram, following a process outlined in my stack overflow post here: http://stackoverflow.com/questions/18098552/using-symfony-2-cli-tools-how-can-i-generate-getters-and-setters-with-correct-t

The result is code that throws E_STRICT notices which we are loathe to suppress for CI reasons, e.g: Runtime Notice: Declaration of ... should be compatible with ... in ... line ...

As mentioned I have asked on Stack Overflow to no avail, as well as the FreeNode IRC channels starting with #symfony. The response from #symfony is that this is a doctrine issue, with suggestions being made that my problem is that I am using the CLI tools.

I don't think it would be too difficult to fix this issue. I had a quick look at the Doctrine\ORM\Tools\EntityGenerator class and Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand and it looks like it should be possible to find the eldest ancestor definition of a function and honour its type hints.

I am open to this being an implementation issue on my end, but I do feel this may be either a bug or an opportunity to improve the CLI tools as for most other purposes they have been a huge benefit to automating my workflow.

Thanks for your time and consideration.






pager produces wrong results on postgresql (DDC-1958)

[DDC-2593] Same bug occurs in MariaDB 5.5 Created: 06/Aug/13  Updated: 06/Aug/13

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

Type: Sub-task Priority: Major
Reporter: Bojidar Hristov Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

//if ($this->platform instanceof PostgreSqlPlatform)

{ //http://www.doctrine-project.org/jira/browse/DDC-1958 $this->getPostgresqlSql($AST, $sqlIdentifier, $innerSql, $sql); //}

That way it works for MariaDB too.






[DDC-2590] Class inheritance - left join between child and parent entities Created: 06/Aug/13  Updated: 25/Mar/14

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

Type: Bug Priority: Major
Reporter: Tomáš Ďuračka Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: inheritance, joins, orm, sql-walker


 Description   

The piece of code given under creates wrong sql to me.

Module is parent entity for BusinessModule entity. Category is joined with BusinessModule.

Module entity is only left joined to its child entity and that's the problem because it contains a field "name" used for filtering. So even if there is no module having the name, categories are still included.

I need the parent entity to be inner joined to child entity not left joined.

File doctrine2/lib/Doctrine/ORM/Query/SqlWalker.php line 353:

// If this is a joined association we must use left joins to preserve the correct result.
$sql .= isset($this->queryComponents[$dqlAlias]['relation']) ? ' LEFT ' : ' INNER ';
$qb->select('c')
->from('Category', 'c')
->join('c.module', 'm', 'WITH', 'm.name = :moduleName')
->setParameter('moduleName', $moduleName);
SELECT c0_.category_id AS category_id0, c0_.title AS title1, c0_.h1 AS h12, c0_.alias AS alias3,
c0_.insertion_fee AS insertion_fee4, c0_.description AS description5, c0_.parent_category_id AS
parent_category_id6, c0_.module_id AS module_id7 
FROM category c0_ 
INNER JOIN business_module b1_ ON c0_.module_id = b1_.module_id 
LEFT JOIN module m2_ ON b1_.module_id = m2_.module_id AND (m2_.name = ?)


 Comments   
Comment by Marek Štípek [ 06/Nov/13 ]

I am experiencing the same issue. The workarround could be to use LEFT JOIN with IS NOT NULL condition... But it also doesnt work after this commit
https://github.com/doctrine/doctrine2/commit/d9c1782a4f6d46f66e9deb2c375830f9192d4482 (i had to revert to dev-master#13c1efb240dd0af25ad0abe230df98ec895892c7)





[DDC-2595] UoW is not supposed to trigger the post-load event for uninitialized proxies. Created: 06/Aug/13  Updated: 06/Aug/13

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

Type: Bug Priority: Major
Reporter: Juti Noppornpitak Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

When one entity have multiple nested levels and associated to 700+ other entities, the ORM exhausts a large amount of memory and execution time which exceeds either the memory limit or the maximum execution time.

Prerequisite:

1. generate an entity, named "Mr. G", with 4 nested levels of association.
2. ensure that the generated entity associating to 700+ entities.
3. create a post-load event listener which may or may not be restricted to uninitialized proxies.

How to Reproduce:

1. have a code to load the "Mr. G" entity.
X. (Done)

Notes:
The initial investigation indicates that UnitOfWork should not trigger the post-load event for uninitialized proxies.

One thing worth-mentioning is that if the event listener ignores all proxies, we will not have this problem. However, some properties (e.g., ones of type TEXT/BLOB) are not loaded into normal entities but they are loaded into the proxies.






[DDC-2596] With Access to ResultSetMapping, Paginator can decide on fetchJoinCollection and useoutputWalker Created: 07/Aug/13  Updated: 07/Aug/13

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: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None





[DDC-2567] auto generated index name cannot be overriden with annotation Created: 23/Jul/13  Updated: 23/Jul/13

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: Nicolas Ricci Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi,

I have an unexpected behaviour when generating SQL from an entity using annotation.

The default indexes name (generated by _generateIdentifierName) are automatically overwriting the name I have specified in my entity.

I have patched the following file https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Schema/Table.php

with:
// check for duplicates
foreach ($this->_indexes as $idxKey => $existingIndex) {
if ($indexCandidate->isFullfilledBy($existingIndex))

{ //return $this; // old implementation unset($this->_indexes[$idxKey]); }

}

but I don't think this is the correct way forward.

Let me know if you require more information

Thanks






[DDC-2560] Schema tool invalid DDL syntax for default values Created: 19/Jul/13  Updated: 19/Jul/13

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

Type: Bug Priority: Major
Reporter: Ben Davies Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: schematool
Environment:

Postgresql



 Description   

Not sure if this is Postgresql specific or not, but here are the reproduction steps:

Have a table with a column setup like so:

ALTER TABLE usr ADD COLUMN contact_count integer;
ALTER TABLE usr ALTER COLUMN contact_count SET NOT NULL;
ALTER TABLE usr ALTER COLUMN contact_count SET DEFAULT 0;

Have a Entity Column Definition like so:

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

orm:schema-tool:update will generate the following SQL:

ALTER TABLE usr ALTER contact_count SET ;

adding

options={"default":0}

to the column definition results in no sql being generated (correctly I assume)



 Comments   
Comment by Marco Pivetta [ 19/Jul/13 ]

The ORM doesn't support default column values.
That's fine-tuning you can do on the column definitions.

Your "workaround" is actually the correct way of dealing with this kind of DDL change.

Comment by Ben Davies [ 19/Jul/13 ]

I realise the ORM doesn't support default values, but the point is that the schematool picks up a diff in the columns, tries to generate a diff, and generates an invalid sql statement. Surely that is a bug?

Comment by Marco Pivetta [ 19/Jul/13 ]

Ben Davies the DBAL is responsible for generating this wrong DDL... Are you able to reproduce this in DBAL only?

Comment by Ben Davies [ 19/Jul/13 ]

Happy to try.

Comment by Ben Davies [ 19/Jul/13 ]

here you go
https://github.com/bendavies/dbal/blob/DBAL-561/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL561Test.php





[DDC-2535] [GH-712] Extra lazy get for inverse side of many-to-many Created: 01/Jul/13  Updated: 01/Jul/13

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 sandermarechal:

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

Message:

This is the cange requested by @stof and @beberlei in PR #710. It implements an extra lazy get on the working side of the relationship. As mentioned in #710 the unit tests fails for reasons I don't quite understand. The error I get is:

```
1) Doctrine\Tests\ORM\Functional\ExtraLazyCollectionTest::testGetIndexByManyToMany
Exception: [PHPUnit_Framework_Error_Notice] Undefined index: joinColumns

Trace:
/home/sander/src/doctrine2/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1665
/home/sander/src/doctrine2/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1610
/home/sander/src/doctrine2/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1701
/home/sander/src/doctrine2/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1115
/home/sander/src/doctrine2/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:746
/home/sander/src/doctrine2/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php:55
/home/sander/src/doctrine2/lib/Doctrine/ORM/PersistentCollection.php:529
/home/sander/src/doctrine2/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php:578
```

If someone with a little more understanding of the Doctrine internals can help me fix this, then we could restore some of the functionality that PR #710 had to remove.






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

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: 1
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).





[DDC-2528] Extracting entities through DQL query resets the previous associations Created: 24/Jun/13  Updated: 25/Jun/13

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

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

Windows 8



 Description   

I have the entities Purchase(owning side) and Product(inverse side) sharing bidirectional many to many relation. Now whatever associations I build between product and purchase entity, those associations are erased if by mistake I happen to run a join query between the products and purchase table. For example look at this code.

$purc = $em->find("\ZC\Entity\Purchase", 1); //Existing purchase entity
//Now this purchase entity is linked to 2 products through the join table
$prod = new \ZC\Entity\Product();
$prod->name= "newly";
$purc->addProduct($prod); //Added a new product to the collection
// print(count($purc->products));
$dql = "SELECT b,c FROM \ZC\Entity\Purchase b join b.products c where      b.id = 1";
$query = $this->entityManager->createQuery($dql);
$purc2 = $query->getResult()[0]; //Now this is same as $purc
print(count($purc->products));   //again prints 2

As you can see, when I have added a new entity $prod to the $purc, the number of products linked to $purc should have increased to 3. It seems the join overrides the previous associations formed. More strange is if I had fetched the products related to $purc from the tables before the join query(the commented code before dql), then the last print statement would have given 3.
I am facing a lot of similar issues.






[DDC-2516] Undefined offset in ObjectHydrator while working with iterableResult Created: 19/Jun/13  Updated: 01/Jul/13

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: Johanny Clerc-Renaud Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

using Symfony2



 Description   

Following this documentation page http://doctrine-orm.readthedocs.org/en/2.0.x/reference/batch-processing.html#iterating-large-results-for-data-processing I tried to create a batch process on 75k entities. But an error came in the ObjectHydrator on line 511 there's an Undefined offset. Now, i just use the SimpleObjectHydrator and it solve the problem. but i'm wondering if it's a real bug or just a miss use of Doctrine.
Reproduce this error could be hard so ask if you want me to give you more informations about it.



 Comments   
Comment by Benjamin Eberlei [ 30/Jun/13 ]

Can you provide more information? The stack trace of the error for example? The entity you try to process+mapping and the DQL query. The current information is not enough to reproduce this error.

Comment by Johanny Clerc-Renaud [ 01/Jul/13 ]

Hello Benjamin,

here is the Entity and with the corresponding Mapping :

Entity.php
    /**
     * @var string
     * @ORM\Id
     * @ORM\Column(name="id_source", type="string", length=32, nullable=false)
     */
    private $idSource;
    
    /**
     * @var string
     *
     * @ORM\Column(name="id_page", type="string", length=32, nullable=false)
     */
    private $idPage;

    /**
     * @var string
     *
     * @ORM\Column(name="url", type="string", length=500, nullable=true)
     */
    private $url;

    /**
     * @var float
     *
     * @ORM\Column(name="similitude", type="decimal", nullable=true)
     */
    private $similitude;

    /**
     * @var string
     *
     * @ORM\Column(name="alerte", type="string", length=512, nullable=true)
     */
    private $alerte;

The Entity have been generated by using this documentation page : http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html

In this project I work with 2 databases, and one of it already exist.

Working with symfony I use the DQL Query obtain with those methods :

EntityRepository.php
    public function getAllUrl($limit)
    {
        $queryBuilder = $this->createQueryBuilder('s');

        $this->setStatsParameters($queryBuilder);

        $queryBuilder->setMaxResults($limit);
        
        return $queryBuilder->getQuery()
                            ->iterate();
    }

    private function setStatsParameters(\Doctrine\ORM\QueryBuilder $queryBuilder)
    {
        $queryBuilder->where('s.similitude > 1')
                     ->andWhere('s.url NOT LIKE :url')
                     ->setParameter('url', 'some_string%');
    }

And here is the stack trace, when the eror comes :

stackTrace.log
Exception trace:
 () at \path\to\project\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php:511
 Symfony\Component\Debug\ErrorHandler->handle() at \path\to\project\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php:511
 Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateRowData() at \path\to\project\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\AbstractHydrator.php:136
 Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateRow() at \path\to\project\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\IterableResult.php:76
 Doctrine\ORM\Internal\Hydration\IterableResult->next() at \path\to\project\src\Compilatio\RecolteurBundle\Command\RecolteurCommand.php:42
 CompanyName\RecolteurBundle\Command\RecolteurCommand->execute() at \path\to\project\vendor\symfony\symfony\src\Symfony\Component\Console\Command\Command.php:244
 Symfony\Component\Console\Command\Command->run() at \path\to\project\vendor\symfony\symfony\src\Symfony\Component\Console\Application.php:906
 Symfony\Component\Console\Application->doRunCommand() at \path\to\project\vendor\symfony\symfony\src\Symfony\Component\Console\Application.php:191
 Symfony\Component\Console\Application->doRun() at \path\to\project\vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Console\Application.php:80
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at \path\to\project\vendor\symfony\symfony\src\Symfony\Component\Console\Application.php:121
 Symfony\Component\Console\Application->run() at \path\to\project\app\console:27

You can also see here the source code that lead to this error :

command.php
  $sources = $urlLoader->getAllSources(50000);

  $number = 0;
  while (($source = $sources->next()) !== false) {
      $number++;
  }
  echo 'Nombre de sources : ' . $number;

There are all the information you ask, if you need more just tell me. For now i can see how to be more specific. Remember that if I switch the hydrator to Query::HYDRATE_SIMPLEOBJECT it solve the bug.

I hope all of this will help.

Regards,

Johanny





[DDC-2504] [GH-696] extra lazy joined test Created: 14/Jun/13  Updated: 14/Jun/13

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 Padam87:

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

Message:

Hi,

This is just a bug report, not an actual PR, you don't have to merge.

When you have a JOINED inheritance, and you have another class, which is related to the parent class of the inheritance, and you only have an association for one of the child classes, EXTRA_LAZY fetch mode creates a fatal error, because it is not joining the parent table to the count query.

There are many ways around this fortunately, but I thought I should report it anyway.






[DDC-2495] Partial objects not working with STI Created: 10/Jun/13  Updated: 11/Jun/13

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

Type: Bug Priority: Major
Reporter: Radoslaw Ejsmont Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: STI, dql, orm, partial
Environment:

Symfony2 project, Doctrine ORM with MySQL database backend


Attachments: File CrossVial.php     File Entity.php     File InjectionVial.php     File Stock.php     File StockVial.php     File Vial.php    

 Description   

When I try to create a query retrieving partial objects of a root class in single table inheritance hierarchy, the resulting SQL includes all fields from the whole class hierarchy.

DQL:
SELECT partial v.

{id, setupDate, flipDate}

FROM VIB\FliesBundle\Entity\Vial v WHERE v.id IN (1,2,3,4,5,6,7,8,9,10)

SQL:
SELECT v0_.setupDate AS setupDate0, v0_.flipDate AS flipDate1, v0_.id AS id2, v0_.type AS type3, v0_.parent_id AS parent_id4, v0_.position_id AS position_id5, v0_.prevPosition_id AS prevPosition_id6, v0_.incubator_id AS incubator_id7, v0_.stock_id AS stock_id8, v0_.male_id AS male_id9, v0_.virgin_id AS virgin_id10, v0_.targetStock_id AS targetStock_id11, v0_.targetStockVial_id AS targetStockVial_id12 FROM Vial v0_ WHERE (v0_.id IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) AND v0_.type IN ('vial', 'stock', 'cross', 'injection')



 Comments   
Comment by Fabio B. Silva [ 10/Jun/13 ]

Could you please provide your entities ?

Thanks

Comment by Radoslaw Ejsmont [ 11/Jun/13 ]

This is the whole class hierarchy.

Comment by Radoslaw Ejsmont [ 11/Jun/13 ]

I have actually noticed, that the "partial" keyword is ignored even for entities that are not using any inheritance schema. So it seems that this keyword is generally ignored.

Right now the following query:

SELECT e, partial p.

{id}

, o, s FROM VIB\FliesBundle\Entity\StockVial e LEFT JOIN e.parent p LEFT JOIN e.position o LEFT JOIN e.stock s WHERE e.setupDate > :date AND e.trashed = false ORDER BY e.setupDate DESC ORDER BY e.id DESC

would result in the following SQL:

SELECT v0_.setupDate AS setupDate0, v0_.flipDate AS flipDate1, v0_.notes AS notes2, v0_.size AS size3, v0_.labelPrinted AS labelPrinted4, v0_.trashed AS trashed5, v0_.temperature AS temperature6, v0_.id AS id7, v1_.id AS id8, r2_.rackRow AS rackRow9, r2_.rackColumn AS rackColumn10, r2_.id AS id11, s3_.name AS name12, s3_.genotype AS genotype13, s3_.notes AS notes14, s3_.vendor AS vendor15, s3_.infoURL AS infoURL16, s3_.verified AS verified17, s3_.id AS id18, v0_.type AS type19, v0_.parent_id AS parent_id20, v0_.position_id AS position_id21, v0_.prevPosition_id AS prevPosition_id22, v0_.incubator_id AS incubator_id23, v0_.stock_id AS stock_id24, v1_.type AS type25, v1_.parent_id AS parent_id26, v1_.position_id AS position_id27, v1_.prevPosition_id AS prevPosition_id28, v1_.incubator_id AS incubator_id29, v1_.stock_id AS stock_id30, v1_.male_id AS male_id31, v1_.virgin_id AS virgin_id32, v1_.targetStock_id AS targetStock_id33, v1_.targetStockVial_id AS targetStockVial_id34, r2_.rack_id AS rack_id35, s3_.sourceCross_id AS sourceCross_id36 FROM Vial v0_ LEFT JOIN Vial v1_ ON v0_.parent_id = v1_.id AND v1_.type IN ('vial', 'stock', 'cross', 'injection') LEFT JOIN RackPosition r2_ ON v0_.position_id = r2_.id LEFT JOIN Stock s3_ ON v0_.stock_id = s3_.id WHERE (v0_.setupDate > '2013-04-11' AND v0_.trashed = 0) AND v0_.type IN ('stock') ORDER BY v0_.setupDate DESC, v0_.id DESC

Please note that ALL properties of parent have been included in the generated SQL.

You can find the whole project (Symfony2) on github: https://github.com/rejsmont/LabDB

Best,

R.

Comment by Radoslaw Ejsmont [ 11/Jun/13 ]

I have noticed that using the setHint(Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD, 1) forces partial load, however then even the entities I want loaded entirely (with proxied references) are partially loaded (i.e. all the references are forced to null, unless explicitly loaded via join).





[DDC-2477] [GH-681] Sequence generator fix Created: 29/May/13  Updated: 29/May/13

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 lighthart:

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

Message:

$this->_sequenceName=$em->getClassMetadata(get_class($entity))->sequenceGeneratorDefinition['sequenceName'];

The sequence generator does not read the class metadata, so if there is table remapping via event listeners, any new entity won't have the appropriate changes in table names.

This pull request adds a remap the Sequence Generator to read the class metadata to determine the sequence name if there is an entity passed to the generate function.

Tests: 1854, Assertions: 6224, Skipped: 96.






[DDC-2452] Additional `WITH` condition in joins between JTI roots cause invalid SQL to be produced Created: 16/May/13  Updated: 27/Mar/14

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

Type: Bug Priority: Major
Reporter: Marco Pivetta Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: dql, sql-walker
Environment:

irrelevant



 Description   

Given a simple Joined Table Inheritance like following:

/**
 * @Entity @Table(name="foo") @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"foo" = "DDC2452Foo", "bar" = "DDC2452Bar"})
 */
class DDC2452Foo
{
    /** @Id @Column(type="integer") @GeneratedValue */
    public $id;
}

/** @Entity @Table(name="bar") */
class DDC2452Bar extends DDC2452Foo
{
}

Following DQL

SELECT foo1 FROM DDC2452Foo foo1 JOIN DDC2452Foo foo2 WITH 1=1

Will produce broken SQL:

SELECT
    f0_.id AS id0, f0_.discr AS discr1 
FROM 
    foo f0_ 
LEFT JOIN bar b1_ 
    ON f0_.id = b1_.id 
LEFT JOIN foo f2_ 
LEFT JOIN bar b3_ 
    ON f2_.id = b3_.id 
    ON (1 = 1)

(please note the duplicate `ON` in the SQL)

That is caused because of the SQL walker producing the JTI filter with already the `ON` clause in it.

That happens because the JTI join conditions are added in https://github.com/doctrine/doctrine2/blob/2.4.0-BETA2/lib/Doctrine/ORM/Query/SqlWalker.php#L823-L825 (`walkRangeVariableDeclaration`), while the additional defined `WITH` conditions are considered in `walkJoinAssociationDeclaration` later on.

Added a test case and fix at https://github.com/doctrine/doctrine2/pull/668






[DDC-2449] Amazon Redshift Support Created: 15/May/13  Updated: 15/May/13

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

Type: New Feature Priority: Major
Reporter: Kirill Fuchs Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Amazon Redshift



 Description   

It would be nice to get doctrine compatible with Amazon Redshift. It uses a Postgres connector but there are some differences. I'm currently facing an issue with the primary id, in Redshift the generation of an id is different from Postgres and so I'm getting errors associated with generating an id.

Here are some references that might be useful:
node-orm faced the same issue and seems like they figured it out: https://github.com/dresende/node-orm2/issues/39

Amazon Manual:
http://awsdocs.s3.amazonaws.com/redshift/latest/redshift-dg.pdf






[DDC-2424] Removing an inherited entity via a delete cascade constraint does not remove the parent row Created: 02/May/13  Updated: 06/May/13

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.3.3
Fix Version/s: None

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

Mysql 5.1.66 / Symfony 2.2.1



 Description   

For a parent class:

/**
 * @ORM\Entity
 * @ORM\Table(name="Base")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"child1" = "Child1", "child2" = "Child2"})
 */

and simple Child1 & Child2 entities.

With another entity (let's call it ExternalEntity) having a bidirectional OneToOne relation owned by Child1:

class Child1 extends Base
{
  /**
   * @ORM\OneToOne(targetEntity="ExternalEntity", inversedBy="xxx")
   * @ORM\JoinColumn(onDelete="CASCADE", nullable=false)
   */
   private theForeignKey;
}

Enough for the context.
The symptoms:

$em->remove(instanceOfExternalEntity);

removes the ExternalEntity row and the Child1 row. But a dangling row in the Base table is still there for the now inexistent Child1 instance.

Though, a manual delete of either the associated Child1 OR Base row and then the ExternalEntity works.

The problem with the cascading deletion of the parent seems to be only present when deleting through a MYSQL cascading delete from another row which has a foreign key on a child. (Not tested with a foreign key on the parent though)



 Comments   
Comment by Benjamin Eberlei [ 04/May/13 ]

Can you show the CREATE TABLE and FOREIGN KEY statements of all the tables involved? It seems the cascade of the foreign keys is not propagated between multiple tables?

Comment by Bruno Jacquet [ 06/May/13 ]

CREATE TABLE Base (id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE Child1 (id INT NOT NULL, foreignKey INT NOT NULL, UNIQUE INDEX UNIQ_179B6E88E992F5A (foreignKey), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

ALTER TABLE Child1 ADD CONSTRAINT FK_179B6E88E992F5A FOREIGN KEY (foreignKey) REFERENCES ExternalEntity (id) ON DELETE CASCADE;
ALTER TABLE Child1 ADD CONSTRAINT FK_179B6E8BF396750 FOREIGN KEY (id) REFERENCES Base (id) ON DELETE CASCADE;

Comment by Bruno Jacquet [ 06/May/13 ]

The problem is that, the SQL model never explicitely tells the DB to delete the corresponding Base when Child1 gets removed. It looks like it is handled by the doctrine entity manager layer and not the actual DB engine (Base has no on delete cascade nor foreign key to its children).
So only doctrine can add the logic here because it knows the entity schema. But in this case, when it is deleted from another table, it looks like the special treatment is not triggered.

Comment by Bruno Jacquet [ 06/May/13 ]

Maybe using

cascade={"remove"}

, instead of

onDelete="CASCADE"

to force the cascading process to be handled by doctrine would workaround the bug... But I prefer to have my DB do the logic work as much as possible.





[DDC-2411] Null values get reset when rehydrating an already managed entity Created: 23/Apr/13  Updated: 09/May/13

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

Type: Bug Priority: Major
Reporter: Simon Garner Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: hydration


 Description   

Scenario:

1) You have an entity with a ManyToOne relation (and probably other kinds too, but this is all I have tested) to another entity which is nullable. For example, let's say you have a Book entity which has an "illustrator" field which refers to a Person entity, representing the person who illustrated the book. If the book is not illustrated then you set the field to null.

2) You fetch a Book (by ID) which has its illustrator set to a particular Person.

3) You set that Book's illustrator to null.

4) Without flushing, you fetch the Book again, using different criteria: for example, by title. Because entities are Identity Mapped, this will run a query but then locate the same instance in memory, and try to hydrate that instance with the old data it just fetched.

5) Any fields on the instance that have modified values retain their new values (for example, if we changed the illustrator to a different Person, this would be retained), BUT any fields on the instance which are null get overwritten with the old data (so if we previously set the illustrator to null, without flushing, it would now be reset to the Person value that it had before).

There seems to be a mistaken assumption here that null values are fields that have not been hydrated, when this is not necessarily the case. Is this the intended behaviour?

The code that causes this behaviour is here: https://github.com/doctrine/doctrine2/blob/e561f47cb2205565eb873f0643637477bfcfc2ff/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php#L471

If you are wondering why anybody would want to fetch the entity again in step 4, my use case for this is the Symfony Validator (but I presume there could be others).

If there are any unique constraints (Symfony ones, not Doctrine ones) on the entity, e.g. if we had a unique constraint on the Book title field, then when validating the Book the Symfony Validator would check if there are already any Book entities with the same title as the Book we're validating. It will find the Book that we are working with, and because entities are identity mapped, it will act upon the same instance, and the situation above occurs.

Code example:

<?php

// Create some entities

$john = new Person();
$john->setName('John Smith');

$jane = new Person();
$jane->setName('Jane Jones');

$joe = new Person();
$joe->setName('Joe Bloggs');

$book = new Book();
$book->setId(123);
$book->setTitle('Book Title');
$book->setIllustrator($john);
$book->setAuthor($jane);

$em->persist($john);
$em->persist($jane);
$em->persist($joe);
$em->persist($book);
$em->flush();

// Now let's try modifying the book

$book = $bookRepository->find(123);
$book->getIllustrator(); // returns Person "John Smith"
$book->getAuthor(); // returns Person "Jane Jones"

// make some changes
$book->setIllustrator(null); // illustrator is now null
$book->setAuthor($joe); // author is now "Joe Bloggs"

// now validate our changes with Symfony Validator
// note: the same effect can also be observed with
// $test = $bookRepository->findBy('title', 'Book Title');
$validator->validate($book);

// what happened to our book??
$book->getIllustrator(); // returns Person "John Smith" <- should be null
$book->getAuthor(); // returns Person "Joe Bloggs" <- correctly retains the new value



 Comments   
Comment by Fabio B. Silva [ 24/Apr/13 ]

Hi Simon,

Could you please try to write a failing test case or paste your entities ?

Cheers

Comment by Benjamin Eberlei [ 09/May/13 ]

Verified by code review that this issue exists, but it will be very tricky to fix, because the null check is there for other reasons as well.





[DDC-2406] Merging of new detached entities with PrePersist lifecycle callback breaks Created: 19/Apr/13  Updated: 28/Nov/13

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: Oleg Namaka Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: merge,, prePersist


 Description   

Merging of new detached entities with PrePersist lifecycle callback breaks:

Code snippet:

    class A
    {
       /**
        *  @ORM\ManyToOne(targetEntity= ...
        *  @ORM\JoinColumn(name=" ...
        */
        protected $b;
        
        public function getB()
        {
            return $this->b;
        }
        
        public function setB($b)
        {
            $this->b = $b;
        }
        
        /**
         *
         * @ORM\PrePersist
         *
         * @return void
         */
        public function onPrePersist()
        {
           if ($this->getB() === null) {
                throw new \Exception('B instance must be defined);
           }
           ....
        }
    }
    
    class B 
    {
    }
    
    $a = new A();
    $b = $em->find('B', 1);
    $a->setB($b);
    $em->persist($a); // works fine as B instance is set
    $em->detach($a);
    
    $a = $em->merge($a) // breaks in onPrePersist

The reason it happens is that the merge operation is trying to persist a new entity created by uow::newInstance($class) without populating its properties first:

 // If there is no ID, it is actually NEW.
    ....
    if ( ! $id) {
        $managedCopy = $this->newInstance($class);

        $this->persistNew($class, $managedCopy);
    } else {
	....

This should happen first for the $managedCopy:

    // Merge state of $entity into existing (managed) entity
    foreach ($class->reflClass->getProperties() as $prop) {
        ....


 Comments   
Comment by Fabio B. Silva [ 28/Apr/13 ]

Benjamin Eberlei, Is this an expected behavior ?

I mean.. This issue is about dispatch the event before copy the original values into the managed instance.
But overall, should $em->detach() trigger @PrePersist events ?

Comment by Benjamin Eberlei [ 01/May/13 ]

Fabio B. Silva he talks about $em->merge() on a detached entity calling pre persist. This should only happen on a NEW entity, not on a DETACHED one.

Comment by Oleg Namaka [ 01/May/13 ]

I tend to disagree with the statement above about pre persist that should not happen on a detached entity being merged back in. If this event handler contains a business logic that this entity needs to be checked against and the detached entity was modified before the merge operation in a way that invalidates it in the prePersist than I will end up with the invalid entity in the identity map. If the merge operation calls persist it must run the prePersist event handler as well for consistency.

If there is a logic that prevents persisting invalid entities why should it bypassed in the merge operation?

Comment by Cory Close [ 28/Nov/13 ]

I can confirm that this bug has not been fixed while using doctrine 2.4

Exactly as Oleg Namaka has described, my organization is trying to use @PrePersist callbacks to enforce validation on new entities.

However, we use an extensive client side framework that sends json back to our server. Our workflow is then:

deserializeJson into detached entity
merge detached entity to get it managed (this will apply our edits to an existing entity, or create a new one if this one is new)
persist

However, some entities run into the above problem while using this workflow, so our validation is not run. I can provide more code samples if required.





[DDC-2405] Changing strategy generates bad query. Created: 19/Apr/13  Updated: 21/Apr/13

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: Van Rotemberg Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

For (unit, acceptance, functional) testing purpose I need to change the strategy of my GameStuff Entity class.

In previous version is was using php instruction below, but since doctrine orm 2.3, it doesn't work anymore.

$orm->getClassMetaData('Entities\GameStuff')->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);

will trigger:

Doctrine\DBAL\DBALException: An exception occurred while executing 'INSERT INTO vbank_accounts (game_id, updated_at, created_at) VALUES (?, ?, ?)' with params

{"1":1000010, "2":0,"3":"2013-04-19 17:16:05","4":"2013-04-19 17:16:05"}

:

SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens



 Comments   
Comment by Benjamin Eberlei [ 20/Apr/13 ]

The problem is that changing ClassMetadata after generating it from the cache is not really supported and depends on the Internal State of other classes. Have you tried creating a completly new EntityManager and then directly setting this? It could be that the SQL for the entity was already generated inside Doctrine, with the ID Generator information at IDENTITY_AUTO.

Comment by Van Rotemberg [ 21/Apr/13 ]

> The problem is that changing ClassMetadata after generating it from the cache is not really supported

Yeah, it is a problem indeed, why set ticket status to resolved ?
Do you think it's normal to have a public method that trigger a fatal error ?

Please fix it or put setIdGeneratorType as private, or AT LEAST add a context exception ...

Comment by Marco Pivetta [ 21/Apr/13 ]

Almost every interaction with metadata outside the `loadClassMetadata` event will cause unexpected problems. I don't think throwing an exception there helps in any way.

Comment by Van Rotemberg [ 21/Apr/13 ]

@marco pivetta

The generation of the actual exception comes from DBALException on the query excetion and point a bad generated query (Invalid parameter number),
when the problem comes from setting ClassMetada, and concerns a problem of cache generated after loadClassMetadata.

Adding an exception is just the fast way pointing where the problem comes from and that "setting metadata after loadMetadata is not supported anymore". (It will spare developper's time that used to set metadata, but also help future contribution)

> Please fix it or put setIdGeneratorType as private, or AT LEAST add a context exception ...
Note: BTW, my favorite solution would be to fix it (re-generate cache, or edit cache, or disable cache or whatever)





[DDC-2401] INDEX BY not working on multiple columns Created: 16/Apr/13  Updated: 18/Apr/13

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

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

Attachments: Zip Archive Testcase.zip    

 Description   

According to the docs on this page:
http://docs.doctrine-project.org/en/latest/reference/dql-doctrine-query-language.html#using-index-by

The following "multi-dimensional index" should be perfectly possible, with a default hydration mode:
SELECT b as business, p as product FROM Businesses b INDEX BY b.id JOIN Products p WITH b.id = p.businessid INDEX BY p.id

However, b.id is completely ignored (it is a numeric primary key).

I tried to go further, giving 2 products a matching barcode and indexing by barcode and then a (unique, numeric) productid. Only the barcode worked as a key and only one of the products with a matching barcode was selected. I used this query to test:
SELECT p FROM Products p INDEX BY p.barcode JOIN p.businessid b INDEX BY p.id

I also flagged the docs, because I don't think a userid should/could be starting from 0.



 Comments   
Comment by Fabio B. Silva [ 18/Apr/13 ]

Hi Quintenvk

Could you please try to write a failing test case ?

Thanks

Comment by Quintenvk [ 18/Apr/13 ]

I added a testcase. Please note that the database settings are to be configured in Core/simplys/simplys.php, and that the dump is in dummy.sql.

Apart from that all should run well immediately.

Comment by Quintenvk [ 18/Apr/13 ]

Fabio,

Please check the zip I just attached. I hope this helps you in finding the problem.

Thanks,
Quinten

Comment by Fabio B. Silva [ 18/Apr/13 ]

Thanks Quintenvk,

SELECT p.barcode, p.id, p.name FROM \core\Simplys\Entity\Products p INDEX BY p.barcode JOIN p.businessid b INDEX BY p.id

In this DQL you are trying to index by scalar values,
I think we does not support that, and a single dimensional array is the expected result in this case.

Also the INDEX BY documentations seems wrong to me.

The given DQL :

 SELECT u.id, u.status, upper(u.name) nameUpper FROM User u INDEX BY u.idJOIN u.phonenumbers p INDEX BY p.phonenumber 

Show the following result :

array
  0 =>
    array
      1 =>
        object(stdClass)[299]
          public '__CLASS__' => string 'Doctrine\Tests\Models\CMS\CmsUser' (length=33)
          public 'id' => int 1
          ..
      'nameUpper' => string 'ROMANB' (length=6)
  1 =>
    array
      2 =>
        object(stdClass)[298]
          public '__CLASS__' => string 'Doctrine\Tests\Models\CMS\CmsUser' (length=33)
          public 'id' => int 2
          ...
      'nameUpper' => string 'JWAGE' (length=5)

Which IMHO represents another DQL, something like :

 SELECT u, p , upper(u.name) nameUpper FROM User u INDEX BY u.id JOIN u.phonenumbers p INDEX BY p.phonenumber
Comment by Quintenvk [ 18/Apr/13 ]

Thanks for your reply Fabio.
Do you think there could be alternatives (apart from a foreach-loop) to achieve the expected result?

Thanks,
Quinten

Comment by Fabio B. Silva [ 18/Apr/13 ]

Not sure if it's exactly the result you need but you can try

Something like :

SELECT p, b FROM \core\Simplys\Entity\Products p INDEX BY p.barcode JOIN p.businessid b INDEX BY p.id

or something like :

SELECT PARTIAL p.{id, barcode, name}, b.{id, attributesYouNeed} FROM \core\Simplys\Entity\Products p INDEX BY p.barcode JOIN p.businessid b INDEX BY p.id

And than :

$result = $query->getArrayResult();
Comment by Quintenvk [ 18/Apr/13 ]

Both produce the same result as the query I had. I think i'll move on to loops after a bit more research, too bad it can't be done (at least for now) though... Would've been nice.

Thanks for your help though!





[DDC-2364] [GH-625] [DDC-2363] Duplicated record with orphanRemoval and proxy Created: 22/Mar/13  Updated: 27/Mar/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: 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.






[DDC-2363] Duplicated record with orphanRemoval and proxy Created: 22/Mar/13  Updated: 27/Mar/14

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!





[DDC-2354] [GH-617] Wrong UnitOfWork::computeChangeSet() Created: 16/Mar/13  Updated: 16/Mar/13

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


 Description   

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

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

Message:

Sometimes some fields are Proxy when compute "changeSet". If it is Proxy, some listeners - example Gedmo sortable listener - belive the value has changed and this leads to chaos.

I check the $actualValue, if it is Proxy, the value didn't change.






[DDC-2351] Entity Listener vs. Event Listener Created: 15/Mar/13  Updated: 15/Mar/13

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

Type: Improvement Priority: Major
Reporter: Fabian Spillner Assignee: Fabio B. Silva
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Entity Listener and Event Listener don't get same events. An example is the onFlush event, which Entity Listener doesn't get. Why are both listeners receiving different events and not same events?

For consistency I'd like to see that both get same events - if I understand the purpose of Entity Listener correctly: it should be an alternative to Event Listener with same functionality but is bound to an entity.



 Comments   
Comment by Benjamin Eberlei [ 15/Mar/13 ]

onFlush and postFlush should be propagated to entity listeners as well





[DDC-2352] [GH-615] Update SqlWalker.php Created: 15/Mar/13  Updated: 15/Mar/13

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


 Description   

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

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

Message:

Always be sure that only a-z characters are used for table alias, otherwise use generic "t" for "table"






[DDC-2339] [GH-605] DDC-2338 Added failing test for composite foreign key persistance Created: 07/Mar/13  Updated: 09/May/13

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: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

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

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

Message:

I've added this test regarding ticket DDC-2338



 Comments   
Comment by Benjamin Eberlei [ 09/May/13 ]

This is documented behavior and would just be an improvement





[DDC-2337] Allow an entity to use its own persister to take advantage of DB level features if necessary Created: 06/Mar/13  Updated: 06/Mar/13

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

Type: New Feature Priority: Major
Reporter: Nathanael Noblet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File persister.patch    

 Description   

I have a situation where I wanted a single table to use INSERT DELAYED. Its an audit log table where I expect each http request to generate many inserts for. In an effort to not over tax the system I implemented a custom Entity Persister so that it would work. This obviously doesn't work with all mapping drivers. However if this is a feature that you think is worth integrating I will fork it on github and complete the implementation alongside any changes/improvements requested...






[DDC-2290] Infer custom Types from the field for query parameters Created: 08/Feb/13  Updated: 28/Jan/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: Matthieu Napoli Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 3
Labels: None


 Description   

When using a mapping Type that declares convertToDatabaseValue, the method is not always called in queries.

Example:

SELECT ... WHERE entity.field = ?1

(with entity.field being of custom type 'the_mapping_type')

Type::convertToDatabaseValue() is correctly called when using:

$query->setParameter('1', 'foo', 'the_mapping_type');

But it is not called when using:

$query->setParameter('1', 'foo');

which gives a query that returns invalid results.

Like other mapping types in this situation, there is no reason the type is not inferred automatically from the field.

I have written a failing test case in Doctrine\Tests\ORM\Functional\TypeValueSqlTest:

    public function testQueryParameterWithoutType()
    {
        $entity = new CustomTypeUpperCase();
        $entity->lowerCaseString = 'foo';

        $this->_em->persist($entity);
        $this->_em->flush();

        $id = $entity->id;

        $this->_em->clear();

        $query = $this->_em->createQuery('SELECT c.id from Doctrine\Tests\Models\CustomType\CustomTypeUpperCase c where c.lowerCaseString = ?1');
        $query->setParameter('1', 'foo');

        $result = $query->getResult();

        $this->assertCount(1, $result);
        $this->assertEquals($id, $result[0]['id']);
    }


 Comments   
Comment by Matthieu Napoli [ 08/Feb/13 ]

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

Comment by Matthieu Napoli [ 08/Feb/13 ]

The test is in this branch: https://github.com/myc-sense/doctrine2/tree/DDC-2290

Comment by Matthieu Napoli [ 29/Oct/13 ]

The organization name has changed so the previous URL is a 404.

Here is the branch containing the failing testcase: https://github.com/myclabs/doctrine2/tree/DDC-2290

Comment by Benjamin Morel [ 28/Jan/14 ]

Any news on this one? Also, I just noticed that it does not cover the original problem I've reported in DDC-2224: I was specifically talking about convertToDatabaseValueSQL() and not convertToDatabaseValue().
My problem is that even when passing the third parameter $type, it does not use the conversion function from convertToDatabaseValueSQL().

Should we reopen DDC-2224?





[DDC-2254] Exporting and restoring a query. Created: 23/Jan/13  Updated: 04/May/13

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

Type: Improvement Priority: Major
Reporter: Dries De Peuter Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql, rebuild, restore, save
Environment:

OSX



 Description   

When you have a queryBuilder and you want to break it down using getDQLParts, You can't restore it by looping over the parts and adding them.

This is what I am doing:

$parts = $qb->getDQLParts();

// save the parts and use them in a different environment.

$newQb = $em->createQueryBuilder();
foreach ($parts as $name => $part) {
  $newQb->add($name, $part);
}


 Comments   
Comment by Dries De Peuter [ 23/Jan/13 ]

I wrote a test showing the issue.

https://github.com/NoUseFreak/doctrine2/commit/8574b79fd3d245532bbe7e310c5cbe083892057a

Comment by