[DDC-3308] Cross platform support for DQL "WHERE ... IN" with multiple fields/columns Created: 13/Sep/14  Updated: 14/Sep/14

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

Type: New Feature Priority: Minor
Reporter: Markus Wößner Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql, mysql, sqlite


 Description   

DQL does not support "WHERE ... IN" statements which refer to more than one field.

Example: While

... WHERE e.id IN (1, 2) ...

is valid DQL

... WHERE (e.id, e.name) IN ((1, "amy"), (2, "fred")) ...

is not.

This was discussed some years ago here https://groups.google.com/forum/#!msg/doctrine-user/bE9RfiF4ZGk/vaiEvsX5_rwJ and it appears that it is not SQL-99. Sqlite does not support it, MySQL does.

As http://sqlfiddle.com/#!7/6169b/1 shows it is not a big deal to transform such a query into an equal query which prevents the usage of "WHERE ... IN" constraints at all. I guess the case "pair(a,b) is not unique" can be safely ignored if redundant pairs are skipped on temp table insertion.



 Comments   
Comment by Marco Pivetta [ 14/Sep/14 ]

This looks everything but trivial to me, especially considering that it introduces usage of UNION, which we also do not support because of portability rules.

Comment by Markus Wößner [ 14/Sep/14 ]

As far as I understand the UNION statement would only be needed when doing an "inline table" approach.

Isn't it a usual technique in Doctrine "AST to SQL output walking" to write temp tables?

Comment by Marco Pivetta [ 14/Sep/14 ]

Yes, we use subqueries in a lot of places, but the paginator walkers are already a real mess from a maintenance PoV, so I don't think we want to go down that route.





[DDC-3293] XML Mappings disallow disabling column prefix for embeddables Created: 01/Sep/14  Updated: 01/Sep/14

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

Type: Bug Priority: Minor
Reporter: Marco Pivetta Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Reference
relates to DDC-3292 [GH-1127] Document embeddables column... Resolved

 Description   

As of DDC-3292, it is not possible to disable the column prefix for embeddables in XML mappings. This example shows that "false" is used as column prefix:

<embedded name="address" class="Address" column-prefix="false" />

A possible solution is to use something like:

<embedded name="address" class="Address" use-column-prefix="false" />

or

<embedded name="address" class="Address" use-column-prefix="true" />





[DDC-3289] Better exception description on some mapping errors Created: 31/Aug/14  Updated: 01/Sep/14

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

Type: Improvement Priority: Minor
Reporter: Luciano Mammino Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mapping, orm, schematool


 Description   

Mapping problems does not always throw very explicit exceptions.

I had this feeling with a very common error:

This behaviour is (currently) not supported by Doctrine 2"

I essentially forgot to add a "mapped-by" attribute in my mappings and, given this generic message, I admit I had to spend a bit of time before being able to spot the mistake.

That's the code that detected the problem and triggered the proper exception.

Doctrine/ORM/Tools/SchemaTool.php
} elseif ($mapping['type'] == ClassMetadata::ONE_TO_MANY && $mapping['isOwningSide']) {
                //... create join table, one-many through join table supported later
                throw ORMException::notSupported();

Within the $mapping variable I see we have a lot of useful information about the problem. Why don't use them to create a very helpful exception message that reports the exact mapped entity and field that raised the error?

IMHO this will grant a better developer experience, especially for doctrine newcomers!



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

Hey Luciano Mammino, could you come up with an exception message that makes sense to you? This kind of improvement is trivial to implement, so it should be quick...

Comment by Luciano Mammino [ 01/Sep/14 ]

Hi Marco Pivetta
I think something like:

One to Many relationships without "mapped-by" attribute are not allowed. (Found in "\Foo\Bar\SomeEntity", field "somefield")

Will be good enough to give developers some clue about where the problem lies. Anyway I'm not sure it covers all the possible cases for this exception and that it is consistent with other error messages within the codebase.





[DDC-3285] \Doctrine\ORM\Event\PreUpdateEventArgs::getOldValue and ::getNewValue return wrong values for ManyToMany association Created: 29/Aug/14  Updated: 10/Sep/14

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

Type: Bug Priority: Minor
Reporter: Reuben Thompson Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux 64 bit, PHP 5.4



 Description   

For most entities the $entityChangeSet[$field] contains an array of
[
0 => old_value
1 => new_value
]
however, for ManyToMany associations it contains a \Doctrine\ORM\PersistentCollection with the current (new) value of the association.

The getOldValue function relies on the other behaviour and simply returns $this->entityChangeSet[$field][0] which will be the first element in the PersistentCollection.

The getNewValue function does likewise but with the second element.

I'd be inclined to alter it to check if $entityChangeSet[$field] instanceof PersistentCollection and return the collection for newValue and throw some kind of Exception for oldValue but don't want to send a patch without checking how you guys would like this to react.



 Comments   
Comment by Reuben Thompson [ 29/Aug/14 ]

I guess this might be related to DDC-3033





[DDC-3270] abstract class database entity generation Created: 23/Aug/14  Updated: 23/Aug/14

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

Type: Bug Priority: Minor
Reporter: Yan Ni Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mysql, orm
Environment:

WAMP symfony2



 Description   

I create an abstract class A using @ORM annotations, then create class B which is a subclass of class A. When I use these to update the mysql database, however, a table for class A was also generated, which shouldn't have happened(because class A is an abstract class).






[DDC-3264] setFetchMode Signature and Documentation Created: 21/Aug/14  Updated: 21/Aug/14

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

Type: Improvement Priority: Minor
Reporter: Andreas Dyballa Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The signature in AbstractQuery should be boolean for fetchmode and the documentation on
http://docs.doctrine-project.org/en/2.1/reference/dql-doctrine-query-language.html
setFetchMode(...,"EAGER"); is not according to the signature.
This is confusing.






[DDC-3263] setFetchmode for ClassMetaData temorarily instead of Query Created: 21/Aug/14  Updated: 21/Aug/14

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

Type: Improvement Priority: Minor
Reporter: Andreas Dyballa Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

SetFetchmode is now woriking in AbstractQuery.

Why dont implement setFetchMode and perhaps further temporarily changes in an ClassMetadata-managing Object. Perhaps to work with a temporarily copy to allow a reset after some action.






[DDC-3261] Bad link in 34.3 Advanced Configuration - Connection Options Created: 20/Aug/14  Updated: 20/Aug/14

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

Type: Bug Priority: Minor
Reporter: Matthew Turland Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: documentation, orm


 Description   

The link to the DBAL section from 34.3 Advanced Configuration - Connection Options results in a 404 HTTP response. This line appears to be responsible.

Link URL as it appears in the current documentation:
http://docs.doctrine-project.org/dbal/2.0/docs/reference/configuration/en






[DDC-3230] Bug in clear cache Created: 25/Jul/14  Updated: 25/Jul/14

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

Type: Bug Priority: Minor
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 64bits
PHP 5.5.4 32 bits
pdo_sql_srv 3.0.2 for php 5.5 32 bits
symfony 2.5
gedmo deletable @ dev-master
Redis 2.8.12
PHPRedis php_redis-2.2.5-5.5-nts-vc11-x86
IIS 7.5



 Description   

1. Redis is used for cache/meta/result caching.
2. Entity has property $deleted with gedmo deletable on it.
3. Removing property $deleted (and all related annotations)
4. Symfony commands:

php app/console doctrine:cache:clear-metadata
php app/console doctrine:cache:clear-query
php app/console doctrine:cache:clear-result
php app/console cache:clear --env=prod --no-debug <-- error on this command

5. [ReflectionException]
Property Entity::$deleted does not exist

Trace:

#0 \vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php(989)
#1 \vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php(571)
#2 \vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(210) <-- CacheRedis driver called here
#3 \vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(114)
#4 \vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\CacheWarmer\ProxyCacheWarmer.php(69)
#5 \vendor\symfony\symfony\src\Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate.php(48)
#6 \app\bootstrap.php.cache(2513)
#7 \app\bootstrap.php.cache(2284)
#8 \vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand.php(128)
#9 \vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand.php(90)
#10 \vendor\symfony\symfony\src\Symfony\Component\Console\Command\Command.php(252)
#11 \vendor\symfony\symfony\src\Symfony\Component\Console\Application.php(894)
#12 \vendor\symfony\symfony\src\Symfony\Component\Console\Application.php(193)
#13 \vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Console\Application.php(96)
#14 \vendor\symfony\symfony\src\Symfony\Component\Console\Application.php(124)
#15 \app\console(27)

Why do i think this is a Doctrine bug and not a Symfony bug? Because

php app/console doctrine:cache:clear-metadata
php app/console doctrine:cache:clear-query
php app/console doctrine:cache:clear-result

have been called successfully so RedisCache should not return cache with $this->fieldMappings containing key "deleted"






[DDC-3223] Failing test (get id return string type) Created: 22/Jul/14  Updated: 22/Jul/14

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

Type: Bug Priority: Minor
Reporter: Thomas Lallement Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux Ubuntu 13.10 / PHP 5.5.3 / Mysql 5.5.x



 Description   

I found an issue in a specific case, when you find a child entity (JOINED) which is linked to another child entity.

If I clone the linked child entity and call getId(), it gives the value as 'string' rather than 'integer'. If I set the property id as public, there is no problem.

If I call getId on the child entity rather than the clone, it gives 'integer' as expected. So it's weird...

See failing test here: https://github.com/doctrine/doctrine2/pull/1086






[DDC-3219] Ensure PersistentCollection->count() is of type int Created: 21/Jul/14  Updated: 21/Jul/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: Minor
Reporter: Flip Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

SQL Server 2012



 Description   

https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/PersistentCollection.php#L566-L577 does not always return an int. How do i know this? because i compare this count with a php count() with strict checking.

If ($collection->count() !== count($somethingElse))

{ throw new Exception($collection->count() . ' is different then ' . count($somethingElse)); }

and at one time this message showed: 3 is different then 3



 Comments   
Comment by Flip [ 21/Jul/14 ]

My colleague told me that it was his mistake somehow, so i don't know how valid this really is !!!





[DDC-3206] Possible to remove inversedBy (use only mappedBy)? Created: 05/Jul/14  Updated: 07/Jul/14

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

Type: Improvement Priority: Minor
Reporter: Ryan Weaver Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi guys!

This is another developer experience situation. Here is the flow:

1. I setup the owning side of a relationship (let's use ManyToMany, the hardest one for this)

2. Later, I decide to setup the inverse side of the relationship. When I do this, I of course add the `mappedBy` attribute so that it points to the exact property/relationship we're dealing with

3. Then, I also need to go back to the owning side and add `inversedBy`.

Why is step 3 (inversedBy) needed? Isn't this redundant information, since the `mappedBy` fully maps out that these 2 associations form different sides of the same relationship? I would love to remove this, I hate explaining to people starting with relationships to now go back to the main entity to add this key. It feels like duplication, which I think people sense.

Of course, I very well may be wrong and it may be needed .

Thanks!



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

I'd suggest doing the opposite: dropping mappedBy.

I'm not sure why JPA introduced this sort of bidirectional mapping, but for practical purposes, it makes it possible for us to load metadata for associations on both sides of the associations. Without having both mappedBy and inversedBy we'd be forced to scan through all existing mappings to find which pieces of the jigsaw fit together.

I don't think we have a good solution for this except for a "build mappings" step that warms up a cache, and that's a very radical architectural change that we can only introduce in 3.x

Comment by Maxime Veber [ 07/Jul/14 ]

Hi, please excuse me if what I say is wrong and do not hesitate to correct me, it's my first immertion in Doctrine code .

So I checked a little bit the situation in the code. I don't see the problem dropping inversedBy. It's easier understandable for the final user.
In facts right now the ManyToMany work very well with only `mappedBy` options so the `invertedBy` is clearly a duplicated information.

The problem for the implementation of this feature is that the ownerSide is decided by a single method for every mappings, so she's quite complexe. So the method decide only on using `mappedBy` and `invertedBy`. This behavior should be modifiable without too much troubles.

https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php#L1353

But another problem here is that should be discuss is that it's a big BC Break.





[DDC-3205] [DX] Interactive Management Command Created: 05/Jul/14  Updated: 06/Jul/14

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

Type: New Feature Priority: Minor
Reporter: Ryan Weaver Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi guys!

This is part of the Symfony Developer Experience Initiative, which I hope can help Doctrine as well . This is a vision for a console tool to help visualize and manage your Doctrine entities. There are so many options and configuration that I think sometimes either (A) people don't even realize what options are available to them or (B) it's difficult to set everything up correctly (especially with relationships).

Imagine an interactive command that did things like:

  • listed your entities
  • listed fields in your entities (and their options, nullable, unique, etc)
  • Allowed you to change field options (e.g. change a field from nullable true to false
  • Allowed you to see your relationships and change options (cascade, JoinColumn stuff, etc)
  • Allowed you to setup relationships or setup the inverse side of a one-sided relationship
  • Added getters/setters
  • Generated helper methods into repositories (e.g. a method to create a query builder that joins a Product over to ProductImages after creating that relationship).

Does anyone see any issues with this? Obviously, this is HUGE, but it wouldn't need to start huge - it could start simply with some visualization and move from there. I think this could bring down the barrier to entry tremendously, and offer (via generation and visualization) some of the benefits of AR magic without that darn magic .

Thanks!



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

TL;DR: dumping details, yes please! modifying files/mappings, no-go.

A couple of things here:

  • listing entities is already available, see orm:info
  • listing all fields and additional details may be useful as an addition to orm:info via a flag. Implementation is also trivial
  • changing mappings via CLI - I'm really against this proposal. I've already tried getting rid of anything codegen-related from the symfony documentation, and I would not want codegen to land in the ORM. Mappings may come from annotations, from xml configs, from yaml or plain PHP files. They may also be processed by listeners and look completely different from the file counterparts. No, let's stay away from any ORM-driven mapping modification.
  • adding getters/setters, generating repositories, adding fields/associations: Doctrine's codegen is actually ONLY meant to provide an easy migration from a legacy DB to ORM entities+mappings, and we're also trying to get away from it in core.

Note that for mappings there's http://www.pulpo18.com/, which eases the path for newcomers. I also developed something for the ZF2 packages (which I must move to a separate library), see http://stackoverflow.com/a/14574952/347063





[DDC-3202] Hydration fails with inhereted overload Created: 01/Jul/14  Updated: 01/Jul/14

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

Type: Bug Priority: Minor
Reporter: Evgen Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: hydration
Environment:

mysql



 Description   

When i use single column with different types hydration not work. No error thrown, but in enity fields wrong data:

Class A

{ /** * @ORM\Column(name="str", type="string") */ protected $value; ... }

Class B extends A

{ /** * @ORM\Column(name="str", type="simple_array") */ protected $value; ... }

column in database created with type tinytext

after query:
SELECT b FROM A;

Entity of class B contain unparsed string in value property, not hydrated as simple_array. But to store B entities i need to parse this strng into array.
in hydrator i see 2 columns str3 and str4 that mapped to "value" propery and to "str" column in database.






[DDC-3201] Add "option" attribute in JoinTable annotation Created: 01/Jul/14  Updated: 01/Jul/14

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

Type: Improvement Priority: Minor
Reporter: Desjardins Jérôme Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hello,

In my project, i try to use Doctrine 2 with all table in MyISAM because there is an existing project structure.

But when i create Many To Many association, i can't specify the MySQL's engine.

I think this option can be add in @JoinTable

I speak "annotation" (because I use annotations) but I suggest, of course, for all formats

Thanks






[DDC-3175] Update documentation for QueryBuilder to give example of using "set()" with parameter Created: 17/Jun/14  Updated: 17/Jun/14

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

Type: Documentation Priority: Minor
Reporter: Max Summe Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.3



 Description   

QueryBuilder->set method uses Expr\Comparison object, which tries to cast values as strings.

When trying to set('updated', new \DateTime) in an update statement, this causes an exception as \DateTime has no __toString method.

Not sure what the fix is - the format for the \DateTime there depends on the platform and ( I think) the type of field.



 Comments   
Comment by Christophe Coevoet [ 17/Jun/14 ]

you should not set a value directly in the DQL query. You should use the query parameters instead.

Comment by Max Summe [ 17/Jun/14 ]

So you're saying it should not be used like this.

$qb = $em->createQueryBuilder();
$qb->update('User', 'u')
->set("u.field", "new value")
->where("u.field = :oldvalue")
->setParameter("oldvalue", "old value");

Instead, it should be:

$qb = $em->createQueryBuilder();
$qb->update('User', 'u')
->set("u.field", ":value")
->where("u.field = :oldvalue")
->setParameter("oldvalue", "old value")
->setParameter("value", "new value");

Is that correct?

If yes, it would be helpful to add an example to the documentation in this page: http://docs.doctrine-project.org/en/latest/reference/query-builder.html





[DDC-3159] CONCAT expression for PostGreSql Created: 10/Jun/14  Updated: 10/Jun/14

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

Type: Improvement Priority: Minor
Reporter: Maxime Colin Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: concat, dql, postgresql
Environment:

PostGreSQL



 Description   

For PostGreSQL, the CONCAT DQL function is translated in concatenation with || operator (which is the default behavior in AbstractPlatform class).

Is there a particular reason to not use the CONCAT PostGreSQL function instead like in MySqlPlatform ?

I ask this cause the concatenation with || operator return null if one of the part is null, whereas CONCAT function will simply ignore null values.






[DDC-3154] Conditions with Value Objects Created: 05/Jun/14  Updated: 05/Jun/14

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

Type: Improvement Priority: Minor
Reporter: Erik A. Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: value-objects


 Description   

I'm quite enthousiastic about Embeddables being added to Doctrine, but it's a pity that true Value Objects, which are compared by their properties, are not supported yet.

Given a Value Object Address with properties street and house number that you can instantiate with new Address("High Street", 1), and a User class that has an Address as Embeddable.

Then, the following is now supported:
DQL1:

SELECT u FROM User u WHERE (u.address.street = :street AND u.address.nr = :number)
    with { 'street' => 'High Street', 'number' => 1 }

Disadvantage: you should know the internal properties when writing your query. That's not how Value Objects usually are compared.

Instead, I expect to be able to do this:
DQL2:

SELECT u FROM User u WHERE (u.address = :address)
    with { 'address' => new Address("High Street", 1)  }

Internally, DQL2 could simply be transformed to the equivalent DQL1 by replacing the condition with conditions for each internal property. The advantage is that the one writing the query does not have to refer to the internal fields; the transformation is hidden.

A complicating factor is that Value Objects are Embeddables, but not every Embeddable is a Value Object. So there is always the question if objects need to be compared by reference or by their properties.

So, perhaps it's an idea to introduce a special operator ~ for comparing objects by their value to make the distinction explicit? Like so:
DQL3:

SELECT u FROM User u WHERE (u.address ~ :address)
    with { 'address' => new Address("High Street", 1)  }.

I created a pull request that contains an idea how the same concept (the ~ operator) might be applied to criterias on in-memory collections.

Just some thoughts and ideas. I'd love to hear some discussion on this as I think it would make Doctrine really powerful in supporting rich, expressive domain models. It would be great if both in-memory collections and DQL supported this!



 Comments   
Comment by Guilherme Blanco [ 05/Jun/14 ]

It should be the same operator, not a new one.
So this is the intended and desired behavior:

SELECT u FROM User u WHERE (u.address = :address)
    with { 'address' => new Address("High Street", 1)  }
Comment by Christophe Coevoet [ 05/Jun/14 ]

This would require to change the DQL to SQL conversion based on the fact that u.address is the path to an embeddable. It might impact performances
Using a separate operator would at least allow to know that it needs a special handling, without having to do complex changes to all places using the = operator.

A complicating factor is that Value Objects are Embeddables, but not every Embeddable is a Value Object. So there is always the question if objects need to be compared by reference or by their properties.

Embeddables cannot be compared by reference. They don't have an identity in the database. The only thing we have to compare them are their properties.

Comment by Erik A. [ 05/Jun/14 ]

True, if we look at the database level, we can only compare by reference. However, if you look beyond ORM and also to the Collections package, then if you want to do a matching on a collection of entities that have an Embeddable by using a Criteria on that Embeddable, then you do have both options (see my referenced pull request). Then two operators might come in handy, so that the additional operator can be introduced to both ORM as well as Collections.

If we would go for one operator (=), then I think the Criteria in Collection also needs to be changed so that it performs a loose comparison on objects and a strict comparison only on scalars. Perhaps that is already out of the scope of the current issue, but either way it would be preferrable to have a consistent solution.

Comment by Christophe Coevoet [ 05/Jun/14 ]

No, saying that we can only compare by reference is wrong. We *cannot* compare by reference (there is no way to reference them).

And talking about the needs of the criteria here is irrelevant, as this discussion is about building the DQL language, not about building the Criteria API. The criteria API can still have a separate operator to deal with value object even if the DQL uses = to compare embeddables. (btw, changing the Criteria comparison to loose on objects would break the comparison of relations, so it is totally impossible as it would be a BC break)

Comment by Guilherme Blanco [ 05/Jun/14 ]

Christophe Coevoet not a performance impact since DQL => SQL is cached.
Adding a new operator resolution requires bigger efforts and I'm pretty sure it'll be slower than converting u.address to multiple clauses (we do it already with composite identifiers).





[DDC-3112] Class Table Inheritance Created: 01/May/14  Updated: 01/May/14

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

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

mysql-5.6.13-winx64, SQL Server 2012, PHP-5.5.4, Windows 7 64 bits professional



 Description   

The documentation on Class Table Inheritance could use some improvements.

1. It's not very clear which classes can have an IDENTITY (auto increment). Consider the example parent: Person, child: Employee. Then add another child: Employer. (this scenario assumes of course that an Employer can never be an Employee). When entering 4 Persons the information in the tables could look like this:
`Parent: (1, Employee), (2, Employee), (3, Employer), (4, Employee) Child Employee: 1,2,4 Child: Employer: 3`
So that means a child can not have an IDENTITY.

Suggestion: specify in docs parent can have IDENTITY, children must not have IDENTITY

2. The parent MUST have an "identifier/primary key" (notice that identifier is not the same as IDENTITY/auto increment). This is not shown in the docs and will throw this:
`Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'No identifier/primary key specified for Entity "MyProject\Model\Person". Every Entity must have an identifier/primary key.'`

Suggestion: specify parent must have identifier/primary key, children primary key will be taken from parent class and must not be specified again in child entity.

3. Is it possible to let a child have it's own identity? And reference the child in the parent table not but the parent's primary key but by a Foreign Key. This blog post here http://blog.liip.ch/archive/2012/03/27/table-inheritance-with-doctrine.html leads me to belief this was once the case (because parent has id and related_id) but perhaps was taken out in later doctrine versions?

Suggestion: specify pros and cons from implementation with FK and without FK (and/or why this changed in history)

4. Show Generated SQL to help understanding. For MySQL:
CREATE TABLE Person (id INT NOT NULL, discr VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
CREATE TABLE Employee (id INT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
ALTER TABLE Employee ADD CONSTRAINT FK_A4E917F7BF396750 FOREIGN KEY (id) REFERENCES Person (id) ON DELETE CASCADE

For SQL Server:
CREATE TABLE Person (id INT NOT NULL, discr NVARCHAR(255) NOT NULL, PRIMARY KEY (id))
CREATE TABLE Employee (id INT NOT NULL, PRIMARY KEY (id))
ALTER TABLE Employee ADD CONSTRAINT FK_A4E917F7BF396750 FOREIGN KEY (id) REFERENCES Person (id) ON DELETE CASCADE

5. Since the parent forces the identity of the child (through a constraint), a child can not manage it's own identity. Which is important to know if you want to merge already existing data. With the constraint on the primary key the database follows very closely the conceptual model in the PHP classes, but looses flexibility on the database schema implementation level. While this could be resolved with a Foreign Key where then you loose strictness of the database and the responsibility shifts back to the application.






[DDC-3087] Entity code generation skip setters Created: 15/Apr/14  Updated: 07/Jun/14

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

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


 Description   

When executing `orm:generate-entities` to generated methods, do not generate setters when entity is readOnly `@ORM\Entity(readOnly=true)`



 Comments   
Comment by Christopher Stea [ 06/Jun/14 ]

I would like to see this feature but at the field level: Maybe my entity has a timestamp property that is auto-generated (uses Timestampable). I want to be able to have a getter but not a setter. Right now if I doctrine:generate and remove the setter function, it is re-created any time i re-run doctrine:generate.

I would suggest having @ORM/readonly as an available setting for properties.

Comment by Marco Pivetta [ 06/Jun/14 ]

I think this use case is simply a customization that should be applied by coding, and not via the generator.

Comment by Christopher Stea [ 07/Jun/14 ]

I have made the required edits and created a pull request:

https://github.com/doctrine/doctrine2/pull/1052
http://www.doctrine-project.org/jira/browse/DDC-3157

In the case of the original request, users can use readonly on every property in the table if they chose to make the entire entity read-only.

Comment by Doctrine Bot [ 07/Jun/14 ]

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

Comment by Marco Pivetta [ 07/Jun/14 ]

See comments on DDC-3157

Comment by Flip [ 07/Jun/14 ]

The PR by Christopher Stea adds a readonly annotation for properties. This ticket is about using the readonly annotation on the class (ORM\Entity) which is already in Doctrine. And just modify the code generator a little bit to skip the setters. Please reopen!!!

Comment by Marco Pivetta [ 07/Jun/14 ]

The PR introduces metadata used solely for the purpose of code generation.

Comment by Flip [ 07/Jun/14 ]

Yes that's not what THIS ticket is about, so please reopen because the PR is related, but not at all a solution to this ticket.

Comment by Marco Pivetta [ 07/Jun/14 ]

Hmm, makes sense. Re-opening then.





[DDC-3036] [doctrine:generate:entities] Created: 17/Mar/14  Updated: 17/Mar/14

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

Type: Improvement Priority: Minor
Reporter: Miguel Simões Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: orm


 Description   

When using an Entity that is extended by some other class (that may not be a Doctrine Entity), the command doctrine:generate:entities should not create getters/setters that are already defined in the parent class.






[DDC-3027] Embeddables on mapped supper classes Created: 13/Mar/14  Updated: 13/Mar/14

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

Type: Bug Priority: Minor
Reporter: Antoine Hedgecock Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Deb 7.3, php 5.5.10-1~dotdeb



 Description   

If you have a embeddable on a mapped superclass you get the following error

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping>
    <embeddable name="DealFinder\Core\ValueObject\Coordinates">
        <field name="latitude"  type="float" precision="10" scale="6" nullable="true"/>
        <field name="longitude" type="float" precision="10" scale="6" nullable="true"/>
    </embeddable>
</doctrine-mapping>
Doctrine\ORM\Mapping\MappingException: Duplicate definition of column 'coordinates_latitude' on entity 'DealFinder\Location\Entity\LocationEntity' in a field or discriminator column mapping.

Moving it to the entity mapping resolves the issues but gives you duplicated code.






[DDC-3001] Date and string values in insert statement are between double quotes (" ") Created: 28/Feb/14  Updated: 28/Feb/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: Minor
Reporter: puspadhar das Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: insert, sqlserver
Environment:

Windows 2012 Server, MS SQL 2012, IBM Server



 Description   

While flushing the entity manager, the sql queries generated for INSERT puts the date and string values inside double quotes and the following error is displayed:
SQLSTATE [21S01, 213]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Column name or number of supplied values does not match table definition.
When I copy the statement and replace the double quotes to single quotes, the query is run.



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

puspadhar das can you provide the SQL query that is being attempted, your fixed version as well as the call to DBAL (or ORM) that is causing this problem?





[DDC-2989] ORM should allow custom index names for foreign associations. Created: 07/Feb/14  Updated: 23/Feb/14

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

Type: Bug Priority: Minor
Reporter: Jonathon Suggs Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm, schematool

Issue Links:
Reference
relates to DBAL-234 Index names are not synchronized by C... Resolved
relates to DBAL-566 Schema Comparator does not identify r... Resolved
is referenced by DDC-2990 [GH-956] Foreign association index names Open

 Description   

Now that the DBAL allows/checks for renamed indexes, the ORM implementation needs to be enhanced to allow custom naming of the indexes for foreign associations.



 Comments   
Comment by Jonathon Suggs [ 07/Feb/14 ]

Here is a full example
https://github.com/jsuggs/schema-issue

I think this mainly has to do with the doctrine auto-generated indexes.

Comment by Marco Pivetta [ 15/Feb/14 ]

IIRC, index names cannot currently be assigned, and are computed automatically - that's why the ORM is behaving like that.

I don't think this needs a fix right now - lowering priority

Comment by Steve Müller [ 15/Feb/14 ]

Jonathon Suggs I also could not reproduce this bug in DBAL. I wonder if that is related to foreign key declarations (ORM relations) only. In fact, you cannot define index names for relations (foreign keys) in ORM at the moment. Therefore ORM always generates index names automatically. If you use custom names for those indexes in your online schema, the comparator will surely output the index renaming statement. I guess defining the index at table level in your mapping manually won't help here either.
Whatsoever I think this is an ORM only issue. If you manually changed your index names "online", you will now get some index rename statements when using the schema tool. Other users explicitly requested this feature. Schemas not in sync have to be upgraded, I guess. So IMO this is rather a "won't fix" in DBAL. However there is a possible improvement to ORM for being able to define index names for foreign keys. The whole topic is rather tricky concerning the comparator. Imagine you have (for whatever reason) multiple indexes with different names that span the exact same columns. How would you expect the comparator to output changes here? Which indexes should be renamed, which shouldn't?

Comment by Jonathon Suggs [ 18/Feb/14 ]

I guess I get it, but its kinda a big deal and I'll have to old off upgrading as a result. I personally find this more of a regression due to the unintended consequences. The schema diff is now 100% useless (to me) as I rename all of my indexes to a more semantic name.

My off the cuff thought on ORM index naming is that you expand the naming strategy to include support for the indexes. Given the full set of criteria you should be able to come up with some sort of semantic naming and only on namespace collision to you "fallback" to a hash of the columns (solves your issues and mine).

Comment by Jonathon Suggs [ 19/Feb/14 ]

To state differently, I (personally) value the schema diff tool much more than custom index (re)naming since the (overall) ability to use custom index names is not complete (due to the ORM issues Steve outlined above).

If the support to (re)name foreign key indexes can't go out in parallel to this, I'd like to offer a middle ground of making the index renaming configurable (ie ability to opt-out of functionality).

Sorry to be negative towards a new feature, but its really an inconvenience for me, and I suspect others since Strate also expressed concerns in the PR.

Let me know how I can be of help in working towards a resolution.

Comment by Benjamin Eberlei [ 19/Feb/14 ]

Jonathon Suggs What do you mean with "just upgraded"? Which to which version? The index renaming and coverage feature is very old already, not sure what is happening. Do you define an index for a relation column?

Comment by Steve Müller [ 19/Feb/14 ]

Benjamin Eberlei This definitely has to do with the comparator now comparing index names also.
Jonathon Suggs Can you please confirm my assumption that this problem is only related to relations and their foreign key indexes? Also can you confirm that it only affects those foreign key indexes which you gave a custom name? Can you please check that?
I don't see any reasonable solution in DBAL for this. The real solution IMO would be to allow custom names in ORM mappings for foreign key realation indexes.

Comment by Jonathon Suggs [ 19/Feb/14 ]

Sorry for the confusion.

Here is the PR that introduced the functionality in question.
https://github.com/doctrine/dbal/pull/473

Benjamin, I had just upgraded DBAL to the latest 2.5 master. This is only indirectly related to the ORM functionality as the ORM SchemaTool uses the DBAL Comparator to generate is schema diff.
Steve, yes this is only related to relations and foreign key indexes that were given a custom name. I documented the use case/scenario here: https://github.com/jsuggs/schema-issue

Steve, I see three potential solutions (in my personal order of preference).
1) Expand the NamingStrategy to allow it to handle the default names of foreign key relation indexes
2) As you suggested, allow for ORM mappings to specify foreign key relation indexes
3) Add a configuration directive that essentially allows for you to ignore renamed indexes (ie. fallback to the previous behavior, prior to PR 473).

I realize that #1 would be a bit more work, but I think offers enhanced functionality. #2 is a good, but would require additional annotations/mappings. #3 is probably the least dev effort but just doesn't feel right (to me).

Again, I don't want to seem critical of the dev effort, but its an unintended consequence that will keep me from being able to upgrade DBAL to 2.5.

Comment by Steve Müller [ 19/Feb/14 ]

Jonathon Suggs You are right the comparator is somewhat responsible for the "unnecesarry" schema diffs it now creates. However its functionality is completely working IMO. Try creating and comparing your schema example on DBAL level only (without utilizing ORM). You will see that it works. I see and understand that those index name updates are annoying but they are not WRONG. If you have a mapping for a relation with an unnamed index and rename this index in your online schema manually, I would even expect the schema tool to generate this diff. Because this is the whole point of the index rename feature. The problem we have here is that there currently is no way in ORM to define the index name on association mappings. There the following happens in your example when comparing the online and offline schema with the schema tool:

(abbreviated to the important steps, chronological order)

1. Collect mapping information and evaluate offline schema
1.1. Schema tool collects relation SQL for Bar -> Foo association and adds an unnamed index "IDX_76FF8CAA8E48560F" to table "bar"
1.2. Schema tool collects custom indexes defined in the mapping for "bar", detects the custom index "IDX_MANY_TO_ONE", tries to add it to the table "bar, but discards it because there is already another index "IDX_76FF8CAA8E48560F" fulfilling the exact same columns (this is how DBAL works ever since to avoid duplicate indexes)

2. Reverse-engineer online schema from database
2.1 Fetch all defined indexes for table "bar" -> adds "idx_many_to_one" to table "bar"

3. Comapre evaluated online schema to evaluated offline schema
3.1 Compare index "idx_many_to_one" (online schema) to index "IDX_76FF8CAA8E48560F" (offline schema) -> suggest index rename from "idx_many_to_one" to "IDX_76FF8CAA8E48560F" because the mapping is your definition and takes precedence.

Just to clarify what happens under the hood and that it is an ORM issue, not DBAL!

Comment by Jonathon Suggs [ 19/Feb/14 ]

Here is a first shot at basic support for allowing the mapping of the index name.
https://github.com/jsuggs/doctrine2/compare/foreign-association-index-names

Comment by Steve Müller [ 19/Feb/14 ]

Jonathon Suggs I have worked on a PR for this already using the exact same approach you just mentioned. However I am not quite sure about ManyToMany yet (because you would have to be able to define both index names there) and also I talked to Benjamin Eberlei and he does not seem to be happy with this approach. So I stopped work on this for the moment.

Comment by Steve Müller [ 19/Feb/14 ]

Moved this to ORM issues.

Comment by Jonathon Suggs [ 19/Feb/14 ]

Steve I both agree and disagree.

I think my underlying issue is your step 1.1. The ORM creates the index named "IDX_76FF8CAA8E48560F" and there is NO extension point for being able to override that behavior. FWIW, I've never been fond of the way that the ORM uses the AbstractAsset::_generateIdentifierName for generating the index and foreign key.

So I definitely agree that its is an ORM issue not DBAL issue . However, as I stated previously, until the ORM is updated/patched to allow for index naming, this (in my opinion) is a regression despite it working the way it currently does (correct or not).

I can close out this issue and open one for ORM. Do you have a old branch and/or ORM ticket that I can reference?

Thanks for engaging in the dialog! I hope to be of assistance in helping come up with a solution that gets everyone happy.

Comment by Steve Müller [ 19/Feb/14 ]

Jonathon Suggs Thanks for updating the description and thanks for assisting on this issue. We will find a solution for this before the final release of 2.5. If we cannot find a good solution until then we might also consider reverting the index renaming feature on DBAL (but I would like to avoid that). I will discuss this issue with the other core devs again and see what we can come up with.

Comment by Jonathon Suggs [ 19/Feb/14 ]

No problem, here is the start of a PR to maybe address the index names
https://github.com/doctrine/doctrine2/pull/956





[DDC-2980] SchemaTool should report what entities cause a duplicate table Created: 13/Feb/14  Updated: 13/Feb/14

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

Type: Improvement Priority: Minor
Reporter: David Buchmann Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

after an afternoon of debugging in all directions, i found out that somebody had copied an entity without changing the table name annotation. i guess next time i see that kind of error, i will look into that possibility sooner, but still, it would be very helpful if the SchemaTool could in addition to "The table with name 'doctrine.fos_user' already exists." also explain which two entities asked for that table to be created.






[DDC-2942] CodeIgniter LIbrary Wrapper Created: 30/Jan/14  Updated: 30/Jan/14

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

Type: Documentation Priority: Minor
Reporter: David Barratt Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hello!

I've created a CodeIgniter Wrapper Library for Doctrine. I believe it works well and is well documented. The library is based on the example found here (http://docs.doctrine-project.org/en/2.0.x/cookbook/integrating-with-codeigniter.html), but is packaged in a nice, easy to install, 3rd-party library.

The library can be found here:
https://github.com/camna/codeigniter-doctrine

Could we replace this page:
http://docs.doctrine-project.org/en/2.0.x/cookbook/integrating-with-codeigniter.html

With a reference to the library?

Thanks!






[DDC-2938] Support all time intervals on DATE_ADD Created: 27/Jan/14  Updated: 27/Jan/14

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

Type: Improvement Priority: Minor
Reporter: Stefano Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The DATE_ADD built-in function of Doctrine supports only the "hour", "month" and "day" intervals. I don't see the point of not having all the intervals available. These should be "minute", "second" and "year". I didn't check compatibility with other database vendors rather than MySQL but I don't think it should be a problem






[DDC-2927] Pass parameters by constructor on load/create new entities Created: 21/Jan/14  Updated: 21/Jan/14

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

Type: Improvement Priority: Minor
Reporter: Jacek Hensoldt Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Unfortunately I found no possibility to pass parameters by constructor on load/create a entity?

I could realize it with live callbacks or through the event manager, but I think it is not a clean solution to configure objects with callbacks or event managers.

Is there a better way?

An example:

Offer-Entity contains a FeastDay-Service and can not exist without the existence of container object (composition). The composition can not be implemented on the database.

class Offer {
	protected $feastDayService = null;

	public function __construct(FeastDayService $service) {
		$this->feastDayService = $service;
	}

	public function isOfferActive($date) {
		if(true === $this->feastDayService->isFeastDay($date) ) {
			return false;
                }
                return true;
        }
}





[DDC-2897] SchemaTool->update() deletes all tables that not belongs to the schema Created: 09/Jan/14  Updated: 09/Jan/14

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

Type: Bug Priority: Minor
Reporter: do.ev. Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

linux, apache, mysql, php, only tested with the zf2-doctrine modules



 Description   

$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
$tool->updateSchema($em->getMetadataFactory()->getAllMetadata());

=> all Tables that not belong to the schema are gone. If you use the commandline tool for update, tables that not belong to the schema are not touched.






[DDC-2894] on-update cascade for one-to-one association Created: 08/Jan/14  Updated: 08/Jan/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: Minor
Reporter: I. S. Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm, schematool, xml


 Description   

I'm trying to use on-update cascade in a one-to-one association but it ends in on-update restrict when I update the database tables.
I'm using XML Definition an my definition for this specific association looks like this:

<one-to-one field="scope" target-entity="Application\Entity\Scope">
<join-column name="scope_id" referenced-column-name="id" nullable="false" on-delete="CASCADE" on-update="CASCADE" />
<cascade>
<cascade-persist />
<cascade-remove />
</cascade>
</one-to-one>

This works pretty well when I use on-update="CASCADE" in a many-to-one association, but one-to-one just ignores it.
When I change the database manually everything works well, but the next update from command line will override it.






[DDC-2864] New type of lock: OPTIMISTIC_FORCE_INCREMENT Created: 18/Dec/13  Updated: 18/Dec/13

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

Type: New Feature Priority: Minor
Reporter: Szurovecz János Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When optimistick locking is being used, the version field is incremented after the update only if the entity itself has been modified. In Domain-Driven Design another kind of locking mechanism is essential: OPTIMISTIC_FORCE_INCREMENT. It means that the version field is always incremented after an update. The lack of this feaure can be realized when only the aggregate root has a version field and some other parts of the aggregate is being modified.

PESSIMISTIC_FORCE_INCREMENT is also an interesting lock type which might be useful as well.






[DDC-2842] Leave out discriminator part of Doctrine' generated SQL Created: 06/Dec/13  Updated: 06/Dec/13

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

Type: Improvement Priority: Minor
Reporter: Roel Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Assume the following AbstractPage model:

/*

  • @ORM\Entity
  • @ORM\Table(name="page")
  • @ORM\InheritanceType("SINGLE_TABLE")
  • @ORM\DiscriminatorColumn(name="type", type="string")
  • @ORM\DiscriminatorMap
  • ( { * "page" = "Page", * "link" = "Link" * }

    )
    */

And the following DQL query:

SELECT p FROM \Page\Model\AbstractPage

The generated SQL will be:

SELECT ... FROM page p0_ WHERE p0_.type IN ('page', 'link')

Now to the question: how can I remove the WHERE clause from this query. On more complex queries this part of the WHERE clause makes it not possible to use some indexes that are defined. This can be resolved by adding type to the indexes, but this makes my indexes larger and I feel this is not necessary.

The AbstractPage is the root in the inheritance tree. Thus we are interested in ALL records in the table. Omiting the WHERE part does precisely that.

So the question is: how can I make Doctrine remove this WHERE part where it is not necessary.






[DDC-2840] Allow "options" on the id element for XmlDriver and AnnotationDriver Created: 06/Dec/13  Updated: 06/Dec/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: Improvement Priority: Minor
Reporter: Marcus Dahlström Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

XmlDriver and AnnotationDriver does not allow for "options" on the "id" element, which the YamlDriver does.

This would help, since specifying "unsigned integer" using column-definition will make the doctrine orm:schema-tool:update think that the unsigned column in the database table doesn't match the signed integer in the mapping.

"From the YamlDriver"
    if (isset($idElement['options'])) {
        $mapping['options'] = $idElement['options'];
    }

Changes would need to take place in Doctrine\ORM\XmlDriver, doctrine-mapping.xsd and Doctrine\ORM\AnnotationDriver

I've come around this by extending the XmlDriver to parse the "options" element, and using a modified xsd file, but it would be helpful it it was actually part of doctrine.






[DDC-2823] SQLSTATE[42000] on insert Created: 27/Nov/13  Updated: 27/Nov/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: Minor
Reporter: Scott Flack Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 (64 Bit), Wampserver (32 Bit), MySQL 5.5.24, PHP 5.4.3, Apache 2.2.22, Symfony 2.2.0



 Description   

If you use a the keyword show as a field, it is not escaped when persisting an entity to the database. It will create and update the table fine, but when inserting it will not. It should either not create the database originally and inform you why, or always escape and work.






[DDC-2822] Replacing object in a OneToOne with OrphanRemoval=true isn't working as expected Created: 26/Nov/13  Updated: 10/Feb/14

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

Type: Bug Priority: Minor
Reporter: Felipe Guaycuru Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

PHP 5.4


Attachments: File DDC2822Test.php    

 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...



 Comments   
Comment by Benjamin Eberlei [ 09/Feb/14 ]

Cannot reproduce this, for me it works, see the SQL log:

CREATE TABLE DDC2822Settings (id INTEGER NOT NULL, medium_id INTEGER DEFAULT NULL, PRIMARY KEY(id), CONSTRAINT FK_B06D3D1FE252B6A5 FOREIGN KEY (medium_id) REFERENCES DDC2822Medium (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)
CREATE UNIQUE INDEX UNIQ_B06D3D1FE252B6A5 ON DDC2822Settings (medium_id)
CREATE TABLE DDC2822Medium (id INTEGER NOT NULL, PRIMARY KEY(id))
"START TRANSACTION"
INSERT INTO DDC2822Medium (id) VALUES (null)
INSERT INTO DDC2822Settings (medium_id) VALUES (?) with {"1":1}
"COMMIT"
"START TRANSACTION"
INSERT INTO DDC2822Medium (id) VALUES (null)
UPDATE DDC2822Settings SET medium_id = ? WHERE id = ? with [2,1]
DELETE FROM DDC2822Medium WHERE id = ? with [1]
"COMMIT"

Testcase attached.

Can you show the code that creates $newMedium in your code?

Comment by Felipe Guaycuru [ 10/Feb/14 ]

Just tested on newest version and I can confirm it no longer happens, so it seems to be fixed!





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

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

Type: Documentation Priority: Minor
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-2788] Create Table If Not Exists - doctrine:schema:update Created: 11/Nov/13  Updated: 11/Nov/13

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

Type: Improvement Priority: Minor
Reporter: jayem Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: command, schematool


 Description   

I am not positive if this issue is in the correct project. Sorry if I placed it in the wrong area.

I was wondering if it would be possible to have the doctrine:schema:update command updated to use CREATE IF NOT EXISTS for tables that already exist.

For example, here is my setup:

Author.php
    /**
     * The relationship between an author and its associated book entities.
     *
     * @ORM\ManyToMany(targetEntity="Book")
     * @ORM\JoinTable(name="authors_books",
     *     joinColumns={@ORM\JoinColumn(name="book_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="author_id", referencedColumnName="id")}
     * )
     */
    protected $books;

The above code is an example, so the exact column names may not be 100% correct. The import aspect is the join table name. If that table already exists in the database, I will get the following error when I run the doctrine:schema:update --dump-sql command:

[Doctrine\DBAL\Schema\SchemaException]
The table with the name 'authors_books' already exists.

This is because it is trying to CREATE TABLE 'authors_books' and that table is already in the database. Could the command instead use CREATE TABLE IF NOT EXISTS 'authors_books' when "IF NOT EXISTS" is available for the configured database type?

Thanks!






[DDC-2772] One class can be mapped to multiple discriminator values Created: 01/Nov/13  Updated: 01/Nov/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: Minor
Reporter: Matthew Ouyang Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

MySQL 5.x



 Description   

I'm not sure if this is intentional or not, but this appears to a valid discriminator map. The problem I am running into is that it's impossible to create an instance of ClassB with a discriminator value "DiscB" (it's always "DiscC" - I'm assuming last one wins here).

<entity name="ClassB" ...>
  <discriminator-map>
    <discriminator-mapping value="DiscA" class="ClassA" />
    <discriminator-mapping value="DiscB" class="ClassB" />
    <discriminator-mapping value="DiscC" class="ClassB" />
  </discriminator-map>
</entity>

Eventhough DiscB and DiscC map to the same class, I do want to maintain some sort of logical separation in the database using the two discriminator values. That does not appear to be possible. I can provide more details about my data model, if necessary.

These are the possible solutions I can think of.

1. Enforce a strict one-to-one relationship between value and class. This means I would have to modify my code to reflect this.
2. (I know this has been rejected before, but I'm in favour of this solution.) Expose the discriminator field but validate it before committing to the database. I'm actually using the discriminator as part of a compound primary key, so this would be very helpful to me.






[DDC-2754] Composer: "cat doctrine >> doctrine.php doctrine.php.bat" Created: 22/Oct/13  Updated: 22/Oct/13

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

Type: Bug Priority: Minor
Reporter: Dominic Guhl Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: composer, packagist
Environment:

Win7 x64, PHP 5.5.3, Composer v2013-10-21 (triggered via NetBeans 7.4)



 Description   

If one is triggering a Composer update, doctrine file content overwrites doctrine.php content and creates doctrine.php.bat with the same content. Before the update, none of these files were existent.

(The summary of this issue suggests what actually happens, not what has been executed by Composer or me, neither it appears in the logs!)

The reason why I reported here first is that these files are only in your repository, from all repositories I have chosen.

Composer Setup was:

    "require": {
        "php": ">=5.3.3",
        "zendframework/zendframework": "2.2.*",
        
        "doctrine/doctrine-module": "0.8.*@dev",
        "doctrine/doctrine-orm-module": "0.8.*@dev"
        
    }, 

...and few requirements were recursively solved on executing update:

    symfony/console (v2.3.6)
    doctrine/orm (v2.4.0)

My first suggest would be that composer can't handle unsuffixed files on Windows. If you can confirm this instead of a bug in Doctrine 2, the Composer project may gets a line dropped?

Possible workaround could be the renaming of doctrine to doctrine.sh.

Thanks!






[DDC-2745] How can I change fetch mode for one query? Created: 16/Oct/13  Updated: 16/Oct/13

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

Type: New Feature Priority: Minor
Reporter: Nikita Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony project



 Description   

Sometimes I need to change fetch mode, but one way for it is write raw DQL and set fetch mode there. That is not so much hard but something like $repo->findAll('EAGER') would be more comforatble



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

The repository API is quite cluttered already. I don't think we want more parameters to the various repository methods.





[DDC-2743] ORM not trowing exception when there is inheritance mapping and type's column's value is missing in discriminator map Created: 15/Oct/13  Updated: 14/Dec/13

Status: Open
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: Improvement Priority: Minor
Reporter: Bojidar Hristov Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It will be good to throw exception otherwise I get

Warning: class_parents(): object or string expected in /Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php on line 40

Warning: array_reverse() expects parameter 1 to be array, boolean given in /Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php on line 257

Warning: Invalid argument supplied for foreach() in /Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php on line 257

This check will be good after line 235 in Doctrine\ORM\Internals\Hydration\ObjectHydrator:

if (empty($className))

{ throw HydrationException::emptyDiscriminatorMapValue($dqlAlias); }

 Comments   
Comment by Benjamin Eberlei [ 13/Dec/13 ]

This can be validated in the ClassMetadataFactory. If you load a child, it will reverse the order of inheritance and start loading the mappings from the root first. The child is then loaded with the full discriminator map and should throw an error if its not in there.

Comment by Luis Cordova [ 14/Dec/13 ]

i am trying this with the basic group at hackingday





[DDC-2721] CLONE - doctrine-mapping.xsd sequence relation-entities Created: 03/Oct/13  Updated: 03/Oct/13

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

Type: Bug Priority: Minor
Reporter: Benoît Burnichon Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I noticed some problems with
the doctrine-mapping.xsd (which apparently is not used to validate the
mapping, but only provided to support code completion in your xml-
editor)

The order in which you define the elements like cascade and join-
column(s) for the relation-entities is currently important since it is
a sequence, but is this really desired? Why force this order? defining
cascade before join-column would make perfect sense as well, doesn't
it.

I looked in the repository and it seems xsd is not valid for all branches 2.1.x, 2.2, 2.3.4, 2.4.0-RC2 and master



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

Yes, order is not enforced in the driver itself either, so it could eventually be removed.





[DDC-2717] Join condition results in wrong SQL when used with CTI Created: 01/Oct/13  Updated: 01/Oct/13

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

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


 Description   

After upgrading from Doctrine 2.1.7 to 2.3.4 I discovered some unexpected behavior. When joining an entity which uses class table inheritance, the join condition will be put after the last left joined inherited table in the final SQL.

To give a concrete example: The Entity "Product" has multiple features. The "Feature" entity has two child tables "ExampleFeature1" and "ExampleFeature2".

The query builder looks like this:

$this->createQueryBuilder('p')
...
->leftJoin('p.features', 'f', 'WITH', 'f.someCriteria = 1')
...

The final SQL:

Doctrine 2.1.7:
SELECT ...
FROM products p
LEFT JOIN features f ON p.id = f.feature_id AND (f.some_criteria = 1)
LEFT JOIN example_feature1 f1 ON f.id = f1.id
LEFT JOIN example_feature1 f2 ON f.id = f2.id

Doctrine 2.3.4:
SELECT ...
FROM products p
LEFT JOIN features f ON p.id = f.feature_id
LEFT JOIN example_feature1 f1 ON f.id = f1.id
LEFT JOIN example_feature1 f2 ON f.id = f2.id AND (f.some_criteria = 1)






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

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

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

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

 Description   

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

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

Generating entity "My\AppBundle\Entity\Job"

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

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


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

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

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

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

Comment by Andy Waterman [ 13/Aug/14 ]

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

Comment by Marco Pivetta [ 13/Aug/14 ]

Andy Waterman you are supposed to manually edit generated entities anyway

Comment by Andy Waterman [ 19/Aug/14 ]

" you are supposed to manually edit generated entities anyway"

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

Comment by Marco Pivetta [ 19/Aug/14 ]

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

Comment by Andy Waterman [ 20/Aug/14 ]

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

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

Comment by Cliff Odijk [ 20/Aug/14 ]

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

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

Comment by Cliff Odijk [ 12/Sep/14 ]

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

Comment by Cliff Odijk [ 12/Sep/14 ]

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

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

        return class_parents($class);




[DDC-2677] Doctrine\Common\Annotations\Reader::getMethodAnnotations sometimes doesn't return an array Created: 13/Sep/13  Updated: 19/Dec/13

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

Type: Bug Priority: Minor
Reporter: Ángel Guzmán Maeso Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Please read https://github.com/schmittjoh/JMSDiExtraBundle/pull/133



 Comments   
Comment by Christophe Coevoet [ 13/Sep/13 ]

Are you using a cached annotation reader ? and if yes, which cache implementation is it ?

Comment by Ángel Guzmán Maeso [ 13/Sep/13 ]

Yes. I am using APC. In my config.yml for production:

<pre>
doctrine:
orm:
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
</pre>

Comment by Christophe Coevoet [ 13/Sep/13 ]

I'm not talking about your ORM cache but about the annotation reader cache (for Symfony, it is configured in FrameworkBundle, and it defaults to a FileCacheReader if you don't configure it explicitly)

Comment by Ángel Guzmán Maeso [ 13/Sep/13 ]

Ok sorry. I am still very new with Symfony and Doctrine.

This is the framework config:
framework:
translator:

{ fallback: en }

secret: %secret%
router:
resource: "%kernel.root_dir%/config/routing.yml"
form: true
csrf_protection: true
validation:

{ enable_annotations: true }

templating:
engines: ['twig']
assets_version: v1.0
default_locale: %locale%
trusted_proxies: ~
session: ~

So it should be FileCacheReader as default config.

PS: I found this that could be related http://stackoverflow.com/questions/14070492/doctrine-annotations-filecachereader-php-invalid-argument

Comment by Jonathan Ingram [ 19/Dec/13 ]

I've noticed this issue since upgrading two things (not sure if either or both are relevant):

1. PHP 5.3 --> 5.5.7
2. Changed to memcached instead of apc for the 3 doctrine ORM cache drivers (note: I haven't touched the framework:annotations:cache configuration so it's the default "file")

I've tried to debug it but no luck figuring out what's going on. As far as I can see, the result is actually an empty array so I am not sure why PHP complains. Makes me wonder if it's a PHP 5.5 bug.

Comment by Marco Pivetta [ 19/Dec/13 ]

Jonathan Ingram can we reduce the scope of the problem? Try using an array cache to remove any caching/serialization related issues.





[DDC-2669] YAML mapping: discriminator map exception Created: 10/Sep/13  Updated: 10/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: Minor
Reporter: Peter Tulala Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: mapping, yaml


 Description   

I'm getting this exception when I generate all entities from YAML using orm:generate-entities:

[Doctrine\ORM\Mapping\MappingException]
Entity class 'Entity\PersonIndividual' used in the discriminator map of class 'Entity\Person' does not exist.

My discriminator map defined in Entity.Person.dcm.yml:

discriminatorMap:
  1: PersonIndividual
  2: PersonCompany
  3: PersonSelfEmployed

Mapping driver probably generates entities in wrong order, so entities defined in discriminator map does not exist when entity Person is being generated.

Note: The easiest workaround is to temporarily remove discriminatorMap definition from entity, generate entities, then put discriminatorMap back and then generate entities again. It would be great if it would be possible to generate all entities in only one step.






[DDC-2667] Collections for OneToMany&ManyToMany relations generated by entity's repository Created: 10/Sep/13  Updated: 10/Sep/13

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

Type: Improvement Priority: Minor
Reporter: Vladimir Schmidt Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: feature


 Description   

The ArrayCollection object for OneToMany or ManyToMany relations is
generated by Doctrine. There is no ability within entity to get acces to it's repository.

This would be very useful nice to specify additionally the method in entity's repository, which could generate collection for the given entity.

An example annotation
/** @ORM\OneToMany(targetEntity="Person", repositoryMethod="findAllowedPersons") */
private $persons;

Advantages

  • optimized query for collection (or even php script)
  • generation of collections can depends on external parameters or internal fields

Problems

  • for such collections adding/removing of elements is not allowed or has be limited





[DDC-2658] Inserting NULL for Undefined Variables Created: 07/Sep/13  Updated: 07/Sep/13

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

Type: Bug Priority: Minor
Reporter: John Julien Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: default, mysql, null
Environment:

CentOS Linux, VMware, MySQL



 Description   

When a MySQL schema contains a line like this:
`failedattempts` int(11) NOT NULL DEFAULT '0',

If a new entity is created and the failedattempts variable is never set, Doctrine attempts to insert the value NULL which throws an SQL error. If a value is undefined for a new object, shouldn't it just be excluded from the insert fields?






[DDC-2655] Query#getOneOrNullResult lets NoResultExceptions through Created: 05/Sep/13  Updated: 11/Oct/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: Minor
Reporter: David Stensland Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Query#execute throws NullResultException sometimes, depending on $hydrationMode and getOneOrNullResult doesn't catch them. Pending pull request adds a test and workaround/fix.



 Comments   
Comment by David Stensland [ 05/Sep/13 ]

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

Comment by Doctrine Bot [ 11/Oct/13 ]

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





[DDC-2644] "final" declaration of ORM\Query class prevents proper unit testing of repositories/models Created: 31/Aug/13  Updated: 31/Aug/13

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

Type: Improvement Priority: Minor
Reporter: Tomáš Lembacher Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm
Environment:

all



 Description   

For proper unit testing it is neccesary to mock all the dependencies from tested class. In repositories/models, one of the dependencies is ORM\Query class. Because it is declared as final, it is neccesary (in order to perform at least some unit test) to create fake entity manager and than lot of assertions. This all won't be needed if ORM\Query won't be declared final, mock can be created and no additional work won't be neccessary in order to create better unit test.






[DDC-2632] Doctrine reverse engineer doesn't honor NOT NULL foreign keys Created: 24/Aug/13  Updated: 24/Aug/13

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

Type: Bug Priority: Minor
Reporter: Paolo Avezzano Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: engineer, mysql, null, nullable, reverse, yaml
Environment:

MAMP, latest version. Symfony up to date



 Description   

In this table, the two foreign keys (which I had to downgrade from primary keys because of Doctrine and then added a separate PK named 'Id') called 'Oggetto' and 'Sistema' have been set as NOT NULL.


-- -----------------------------------------------------
-- Table `mydb`.`Composizione`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`Composizione` ;

CREATE  TABLE IF NOT EXISTS `mydb`.`Composizione` (
  `Id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `Oggetto` INT UNSIGNED NOT NULL ,
  `Sistema` INT NOT NULL ,
  INDEX `fk_Oggetto_has_Sistema_Sistema1_idx` (`Sistema` ASC) ,
  INDEX `fk_Oggetto_has_Sistema_Oggetto1_idx` (`Oggetto` ASC) ,
  PRIMARY KEY (`Id`) ,
  CONSTRAINT `fk_Oggetto_has_Sistema_Oggetto1`
    FOREIGN KEY (`Oggetto` )
    REFERENCES `mydb`.`Oggetto` (`Id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_Oggetto_has_Sistema_Sistema1`
    FOREIGN KEY (`Sistema` )
    REFERENCES `mydb`.`Sistema` (`Id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

Converting into Yaml here it is what I get.

    type: entity
    table: Composizione
    fields:
        id:
            id: true
            type: integer
            unsigned: true
            nullable: false
            column: Id
            generator:
                strategy: IDENTITY
    manyToOne:
        oggetto:
            targetEntity: Oggetto
            cascade:      {  }
            mappedBy:     null
            inversedBy:   null
            joinColumns:
                Oggetto:
                    referencedColumnName: Id
            orphanRemoval: false
        sistema:
            targetEntity: Sistema
            cascade:      {  }
            mappedBy:     null
            inversedBy:   null
            joinColumns:
                Sistema:
                    referencedColumnName: Id
            orphanRemoval: false
    lifecycleCallbacks: {  }

Basically it lost in translation the NOT NULL part.
To make it work I had to manually add two "nullable: false" lines as I did below:

    type: entity
    table: Composizione
    fields:
        id:
            id: true
            type: integer
            unsigned: true
            nullable: false
            column: Id
            generator:
                strategy: IDENTITY
    manyToOne:
        oggetto:
            targetEntity: Oggetto
            cascade:      {  }
            mappedBy:     null
            inversedBy:   null
            joinColumns:
                Oggetto:
                    referencedColumnName: Id
                    nullable:     false
            orphanRemoval: false
        sistema:
            targetEntity: Sistema
            cascade:      {  }
            mappedBy:     null
            inversedBy:   null
            joinColumns:
                Sistema:
                    referencedColumnName: Id
                    nullable:     false
            orphanRemoval: false
    lifecycleCallbacks: {  }

Is it a bug or am I missing something?

Regards,
Paolo Avezzano






[DDC-2606] orm:generate-proxies should generate type mappedSuperclass Created: 09/Aug/13  Updated: 09/Aug/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: Minor
Reporter: Thomas Hava Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

By using the concept of mapperSuperClasses and entity classes to enable inheritance features, the proxy classes are being auto generated as expected. If i switch to production mode and try to generate all classes manually by calling the orm:generate-proxies command, the mappedSuperClasses wont be auto generated, since this type is explicitely excluded in the skipClass method.

In my opinion it is viable that the user can access either the mappedSuperClass (e.g. during a dql statement) directly or the entity class. Therefore i propose to change the skipClass method (AbstractProxyFactory.php) as shown below.

protected function skipClass(ClassMetadata $metadata)

{ /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */ return $metadata->getReflectionClass()->isAbstract(); }

If this is not as intended, this should be at least made configureable during the orm:generate-proxies command call.



 Comments   
Comment by Marco Pivetta [ 09/Aug/13 ]

Mapped superclasses don't need to be proxied, since the ORM won't ever have references to objects being an exact instance of a mapped superclass (not any of its subclasses). I guess they should be disabled for development mode too instead

Comment by Thomas Hava [ 09/Aug/13 ]

The ORM has references if the developer decides to use this class directly (isn't this viable?). Another example where i ran into this issue is in combination with relations and dql queries. If there's a relation e.g. book authors and their books (One-to-many).

*) Entities:
Author
EntityAuthor
Book
EntityBook

If i want to select a list of books and their authors i would use this dql statement:
SELECT b FROM EntityBook b JOIN b.author a

After querying the data i could do something like
foreach ($books as $book)

{ echo $book->getAuthor()->getName(); }

The "getAuthor()" method call does simply return the mapped super class "Author" instead of "EntityAuthor", which leads to the proxy class requirement!





[DDC-2594] schema-tools:update fails to sync options={"default" = 0} to the database 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: Bug Priority: Minor
Reporter: Pedro Cordeiro Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Specifying DEFAULT 0 on my database will cause doctrine to throw an out-of-sync warning when validating my mappings (if the options=

{"default"=0} isn't defined), but the inverse is not true. Doctrine will say my entity is synced, even if I specified options={"default"=0}

and my database doesn't have a default value.



 Comments   
Comment by Marco Pivetta [ 06/Aug/13 ]

That's normal, advanced "options" are not taken into account when computing changes in the schema (for now)





[DDC-2570] Doctrine CLI Tools - Clear All Cache Created: 24/Jul/13  Updated: 08/Feb/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM, Tools
Affects Version/s: 2.3.4
Fix Version/s: 2.x, 2.5

Type: Improvement Priority: Minor
Reporter: Frederick Marcoux Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: Cli, cache, orm


 Description   

It would be nice to be able to clear all cache one shot instead of clearing them one after one...

Like this:

root$ ./doctrine orm:clear-cache:all

Instead of:

root$ ./doctrine orm:clear-cache:metadata
root$ ./doctrine orm:clear-cache:result
root$ ./doctrine orm:clear-cache:query






[DDC-2569] Unable to reverse engineer non "dbo" schema table Created: 24/Jul/13  Updated: 24/Jul/13

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

Type: Bug Priority: Minor
Reporter: Paul Mansell Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: sqlserver


 Description   

I am unable to reverse engineer a table with a non "dbo" schema from Microsoft SQL Server 2008. The "getListTablesSQL" SQL returns a list of tables without the schema name. An alternative would be to use the SQL :

SELECT '['+SCHEMA_NAME(schema_id)+'].['+name+']' AS name FROM sys.tables

instead - this returns the list of table with the schema name.






[DDC-2556] Proxy getId() different code generated when using Trait Created: 16/Jul/13  Updated: 16/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: Minor
Reporter: Eduardo Oliveira Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None


 Description   
class Timezone {
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="smallint", nullable=false, options={"unsigned": true})
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
}

If I replace that code with a Trait with equal code and use it on the entity the proxy will be generated different.

Without trait:

    /**
     * {@inheritDoc}
     */
    public function getId()
    {
       	if ($this->__isInitialized__ === false) {
            return (int)  parent::getId();
        }


       	$this->__initializer__ && $this->__initializer__->__invoke($this, 'getId', array());

       	return parent::getId();
    }

With trait:

    /**
     * {@inheritDoc}
     */
    public function getId()
    {

        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getId', array());

        return parent::getId();
    }

And in this code:

$timezone = $this->timezoneRepository->findReadOnly(
    $campaign->getTimezone()->getId()
);

I get:
Doctrine\ORM\ORMException: The identifier id is missing for a query of EB\Core\KernelBundle\Entity\Common\Timezone

$campaign->getTimezone()->getId()
Is returning null.

About the findReadOnly is just a wrapper that will fetch from cache if not there fetch from DB, anyway if I change it to find() exact same problem

My versions of doctrine:

$ php composer.phar show -i | grep doctrine
doctrine/annotations                   v1.1.2             Docblock Annotations Parser
doctrine/cache                         v1.0               Caching library offering an object-oriented API for many cache backends
doctrine/collections                   v1.1               Collections Abstraction library
doctrine/common                        2.4.0-RC4          Common Library for Doctrine projects
doctrine/data-fixtures                 dev-master 6924952 Data Fixtures for all Doctrine Object Managers
doctrine/dbal                          2.4.0-RC2          Database Abstraction Layer
doctrine/doctrine-bundle               v1.2.0             Symfony DoctrineBundle
doctrine/doctrine-fixtures-bundle      dev-master 512fc0f Symfony DoctrineFixturesBundle
doctrine/doctrine-migrations-bundle    dev-master 5fc1167 Symfony DoctrineMigrationsBundle
doctrine/inflector                     v1.0               Common String Manipulations with regard to casing and singular/plural rules.
doctrine/lexer                         v1.0               Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.
doctrine/migrations                    dev-master ced3b41 Database Schema migrations using Doctrine DBAL
doctrine/orm                           2.4.0-RC2          Object-Relational-Mapper for PHP
gedmo/doctrine-extensions              v2.3.6             Doctrine2 behavioral extensions
stof/doctrine-extensions-bundle        dev-master 6577f23 Integration of the gedmo/doctrine-extensions with Symfony2


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

Is the problem here the repository or just the trait method?

Can you please clean up the issue to insulate only the affected part? What is `getId` returning on that kind of object?

Comment by Eduardo Oliveira [ 16/Jul/13 ]

Marco I will try to do better, I will try to do make a test case that proves this.

But i can leave here already more info:

  • There is an entity Campaign that have a Timezone (ManyToOne in Campaign side);
  • This entity Campaign is fetch (with lazy in all associations) and serialized and put in cache;
  • This entity Campaign don't have timezone itself, but $campaign->getTimezone()->getId() hit the return (int) parent::getId(); on proxy not making any query to get the timezone, in the case with trait the proxy code is different and it returns null
Comment by Marco Pivetta [ 16/Jul/13 ]

Eduardo Oliveira is the proxy in a detached state when you do this? What happens if (with an existing identifier) you do following?

var_dump($entityManager->getReference('Timezone', 123)->getId());
Comment by Eduardo Oliveira [ 16/Jul/13 ]
var_dump ( $this->timezoneRepository->getEM()->getReference('EBCoreKernelBundle:Common\Timezone', 1)->getId() ); // 1

Marco yes is on detached mode, and I know that, I'm relying on the proxy to get the ID, because I don't want any queries being "issued", so I'm doing like

$campaign = $campaignRepository->findReadOnly(10); // hit cache
$timezoneRepository->findReadOnly($campaign->getTimezone()->getId() /* rely on proxy */); // hit memcache

This just work in the last versions of Doctrine that have lazy getId(), but it looks that for traits something wrong happens on the generation of Proxy.

If on Entity timezone I use the trait but override the getId() everything works perfect again.

Comment by Marco Pivetta [ 16/Jul/13 ]

Eduardo Oliveira does this also happen with 2.3.x? (asking because the proxy generation logic was rewritten for 2.4)

Comment by Eduardo Oliveira [ 16/Jul/13 ]

2.3 the proxy is quite different but the essence of the problem remains:

Proxy with trait (doesn't work, because as far as I know will try to make a query in detach mode):

    public function getId()
    {
        $this->__load();
        return parent::getId();
    }

Proxy without trait (works well):

    public function getId()
    {
        if ($this->__isInitialized__ === false) {
            return (int) $this->_identifier["id"];
        }
        $this->__load();
        return parent::getId();
    }
Comment by Marco Pivetta [ 16/Jul/13 ]

Ok, so at least I now know it's not an issue with the upgrade, but it was also borked before. Thanks for following along till here: I'll work on a patch as soon as I have time.





[DDC-2531] ManyToManyPersister does not take Custom Types into account Created: 26/Jun/13  Updated: 26/Jun/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: Minor
Reporter: George van Vliet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

When two entities, both using a custom type for the "@Id" column, have a "@ManyToMany" (bidirectional) relationship, the ManyToManyPersister does not take into account the custom type of the referenced id columns and therefore does not convert the values using the appropriate "convertToDatabaseValue" function.

The entities themselves are saved propery, but the insertion into the join table always fails.






[DDC-2523] Proxies and serializable Created: 23/Jun/13  Updated: 23/Jun/13

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

Type: Improvement Priority: Minor
Reporter: Nikita Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi! Why Doctrine proxies classes extends object, instead of decorate it?
I mean's this pattern http://en.wikipedia.org/wiki/Decorator_pattern.



 Comments   
Comment by Christophe Coevoet [ 23/Jun/13 ]

The proxy needs to extend the original class, otherwise it would not pass an instanceof check





[DDC-2522] When changing a manyToMany relationship to a stand alone table with the same table name, doctrine fails to properly update schema. Created: 20/Jun/13  Updated: 05/Nov/13

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

Type: Bug Priority: Minor
Reporter: Jeremy Moore Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: None
Environment:

Discovered while using doctrine orm in Symfony 2.1. MySQL



 Description   

To start with I created a manyToMany relationship in my user entity to my referrers entity. The association was named "referrals" and used a table named "user_referrals" as the manyToMany join table.

I later removed the manyToMany join association in favor of a stand-alone entity. I created an entity named UserReferrals. I kept the table name "user_referrals".

When doctrine attempts to update the mysql database schema, I receive this error...

SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key

This is the SQL attempting to be executed:
ALTER TABLE user_referrals ADD id INT AUTO_INCREMENT NOT NULL, ADD created DATETIME NOT NULL, ADD updated DATETIME NOT NULL, ADD status VARCHAR(255) NOT NULL, CHANGE referrer_id referrer_id INT DEFAULT NULL, CHANGE user_id user_id INT DEFAULT NULL

Is this a bug? Running the SQL directly in MYSQL also fails with the same error.



 Comments   
Comment by Peter Rehm [ 05/Nov/13 ]

In the SQL Statement there is the primary key definition missing. In your case the adjustment to

ALTER TABLE user_referrals ADD id INT AUTO_INCREMENT NOT NULL, ADD PRIMARY KEY (id), ADD created DATETIME NOT NULL, ADD updated DATETIME NOT NULL, ADD status VARCHAR(255) NOT NULL, CHANGE referrer_id referrer_id INT DEFAULT NULL, CHANGE user_id user_id INT DEFAULT NULL

should make it.

If have the same issue where the schema tool / migrations generated the following statements:

ALTER TABLE ArticleToSet DROP PRIMARY KEY
ALTER TABLE ArticleToSet ADD id INT AUTO_INCREMENT NOT NULL, CHANGE article_id article_id INT DEFAULT NULL, CHANGE articleSet_id articleSet_id INT DEFAULT NULL
ALTER TABLE ArticleToSet ADD PRIMARY KEY (id)

Updating it manually to the following fixes it:

ALTER TABLE ArticleArticleToSet DROP PRIMARY KEY"
ALTER TABLE ArticleArticleToSet ADD id INT AUTO_INCREMENT NOT NULL, ADD PRIMARY KEY (id), CHANGE article_id article_id INT DEFAULT NULL, CHANGE articleSet_id articleSet_id INT DEFAULT NULL

The situation appeared when I have changed from a composite key to a separate key.





[DDC-2515] Schema tool ignores index names in mapping file and uses generated name Created: 18/Jun/13  Updated: 21/Jun/13

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

Type: Bug Priority: Minor
Reporter: Daniel Huss Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File ddc-2515.testcase.patch    

 Description   

I have defined an index on a foreign key colum in my .dcm.xml mapping file:

<indexes>
      <index name="ix_date_created__client_id" columns="date_created,client_id"/>
      <index name="ix_user_id" columns="user_id"/>
</indexes>

However, the resulting CREATE TABLE statement includes:

    INDEX IDX_4848DD9FA76ED395 (user_id), 
    INDEX IDX_4848DD9F4239E22F (accessgroup_id), 
    INDEX IDX_4848DD9FD2112630 (usergroup_id), 
    INDEX ix_date_created__client_id (date_created, client_id), 

So Doctrine seems to be auto-generating indexes for all foreign key columns. I'm assuming this is a feature, even though I'd argue that there are real-life examples where the mere presence of a foreign key constraint does not justify indexing that column.

Anyway, the expected behavior is that Doctrine does not replace existing indexes with generated ones. I will attach a failing test case unless this bug is immediately dismissed as wontfix.



 Comments   
Comment by Daniel Huss [ 21/Jun/13 ]

Test case for SchemaToolTest





[DDC-2509] Add CLI detection for the APC check on Console cache commands Created: 17/Jun/13  Updated: 17/Jun/13

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

Type: Improvement Priority: Minor
Reporter: Jonathan Cardoso Machado Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

There is some instanceof checks on the \Doctrine\ORM\Tools\Console\Command\ClearCache* commands to detect if APC is being used, they were introduced here: https://github.com/doctrine/doctrine2/commit/8efae0b232210b27200f2709e7fcb24c7f02c5de

I would like to know if it's possible to add a CLI check too, something like:

if ($cacheDriver instanceof Cache\ApcCache && PHP_SAPI === 'cli' )

Yeah, I know that those are CLI commands, and so the check looks like unecessary, however, in the particular case that I found it's necessary, I'm running the commands under an WebUI:
Before the modification:

After:



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

CLI commands are not meant to be used in WEB environment (at least not the Symfony CLI ones). You should probably replicate that logic instead.





[DDC-2479] Add possibility to only query for root entities in a class table inheritance Created: 30/May/13  Updated: 30/May/13

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

Type: Improvement Priority: Minor
Reporter: Steve Müller Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql,, inheritance


 Description   

It is not possible to query for root/topmost class entities (only) in a class table inheritance situation without extra JOINs to the child entities/classes.

E.g.
Person -> root entity/class
Employee -> child entity/class extending Person

The DQL:

SELECT p
FROM Person p;

also joins Employee even though I am not interested in Employee properties.

Person is the base class in this use case and it should be possible to only retrieve those information. Thinking of OOP, if I instanciate Person I do not have any reference to its child either.
This is especially useful for large base tables where you want to only retrieve base information without inferring the childs.

IMO the DQL should be modified to allow selecting root/base information only, similar to the INSTANCE OF operator, that allows selecting specific childs only.






[DDC-2467] Incorrect work with default values, indexes, autoincrement (patch attached) Created: 23/May/13  Updated: 28/May/13

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

Type: Improvement Priority: Minor
Reporter: And Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File ORM.patch    

 Description   

If you use in your MySQL database default values, indexes or string primary key, you get incorrect mapping by mapping generator. For get it - just use in database one or more from listed abilities, generate mapping for that and then try to dump-sql with schema-tool:update.

Hope you fix it. Tnx!



 Comments   
Comment by Marco Pivetta [ 23/May/13 ]

Marked as minor improvement - thank you for the patch!

Comment by And [ 28/May/13 ]

When it will be merged? Maybe, planned version?

Comment by Marco Pivetta [ 28/May/13 ]

And such a patch requires failing tests before being applied - that's up to whoever picks it up.

Comment by And [ 28/May/13 ]

So if I add patch with tests - it will be merged? =)

Comment by Marco Pivetta [ 28/May/13 ]

Most probably - you can open a pull request against the current ORM master for that





[DDC-2464] useless index for the middle table of many-to-many relationship Created: 21/May/13  Updated: 21/May/13

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

Type: Improvement Priority: Minor
Reporter: scourgen Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: ddl, schematool


 Description   

I have entity A and B, the relationship between A and B is many-to-many. which means Doctrine2 will generate a middle table called AB for me.

entity A:

class Station {
    /**
     * @ORM\ManyToMany(targetEntity="Fun", mappedBy="stations")
     */
    protected $funs;
}

entity B:

class Fun {
    /**
     * @ORM\ManyToMany(targetEntity="Station", inversedBy="funs")
     * @ORM\JoinTable(name="stations_have_funs")
     */
    protected $stations;
}

the schema of middle table stations_have_funs:

CREATE TABLE `stations_have_funs` (
  `fun_id` int(11) NOT NULL,
  `station_id` int(11) NOT NULL,
  PRIMARY KEY (`fun_id`,`station_id`),
  KEY `IDX_45C921911CA4BE49` (`fun_id`),
  KEY `IDX_45C9219121BDB235` (`station_id`),
  CONSTRAINT `FK_45C921911CA4BE49` FOREIGN KEY (`fun_id`) REFERENCES `funs` (`id`) ON DELETE CASCADE,
  CONSTRAINT `FK_45C9219121BDB235` FOREIGN KEY (`station_id`) REFERENCES `stations` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

I noticed that there are 2 useless index(fun_id and station_id). Since fun_id and station_id are the primary key of this table. Do we really need 2 extra/duplicated index ?






[DDC-2462] [GH-674] Shortcut for force Created: 20/May/13  Updated: 03/Sep/14

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

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


 Description   

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

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

Message:



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

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

Comment by Doctrine Bot [ 03/Sep/14 ]

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

Comment by Doctrine Bot [ 03/Sep/14 ]

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





[DDC-2454] To-Many OrderBy mechanism should allow many-to-one associations Created: 16/May/13  Updated: 16/May/13

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

Type: Improvement Priority: Minor
Reporter: Oleg Namaka Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: association, orderBy


 Description   
class ProductCategory
{
    /**
     * Store
     *
     * @var Store
     *
     * @ORM\ManyToOne(targetEntity="Store")
     * @ORM\JoinColumn(name="store_id", referencedColumnName="store_id")
     */
    private $Store;

    /**
     * storeId (for ordering in Product::ProductCategories only)
     *
     * @var integer
     *
     * @ORM\Column(name="store_id", type="integer")
     */
    private $storeId;
...

class Product
{
    /**
     * Associated categories
     *
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity="ProductCategory", mappedBy="Product")
     * @ORM\OrderBy({"storeId"="ASC"})
     */
    private $ProductCategories;
}
}

If it is possible now to sort the ProductCategories collection by the storeId field, it should also be possible to sort them by the Store association. Currently a set of two fields is required: Store as a regular Many-To-One association and if a need arises to be able to use it to sort the One-To-Many collections then storeId needs to be added to the ProductCategory entity. In that case the ProductCategory entity does not pass the schema validation but is perfectly usable.

This should be allowed:

class Product
{
    /**
     * Associated categories
     *
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity="ProductCategory", mappedBy="Product")
     * @ORM\OrderBy({"Store"="ASC"})
     */
    private $ProductCategories;
}






[DDC-2381] Pagination query can be simplified when simple joins are applied Created: 31/Mar/13  Updated: 29/Nov/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: Improvement Priority: Minor
Reporter: Sergey Gerdel Assignee: Marco Pivetta
Resolution: Unresolved Votes: 2
Labels: paginator

Attachments: HTML File EXPLAIN.htmL     HTML File EXPLAIN1.html     HTML File EXPLAIN2.html     HTML File EXPLAIN3.htm     HTML File EXPLAIN4.htm    

 Description   

Hi.
In mysql db table i have > 200,000 items.
I use native doctrine pagination for paging the items list.
But generated query that gets ids for items list in paging works more then 150 sec on my workstation

SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, m0_.title AS title1, m0_.text AS text2, m0_.price AS price3, m0_.originalPrice AS originalPrice4, m0_.condition_type AS condition_type5, m0_.image_1 AS image_16, m0_.image_2 AS image_27, m0_.image_3 AS image_38, m0_.image_4 AS image_49, m0_.image_5 AS image_510, m0_.video AS video11, m0_.contact_email AS contact_email12, m0_.contact_name AS contact_name13, m0_.contact_phone AS contact_phone14, m0_.contact_type AS contact_type15, m0_.published AS published16, m0_.type AS type17, m0_.status AS status18, m0_.highlight AS highlight19, m0_.urgent AS urgent20, m0_.topads AS topads21, m0_.period AS period22, m0_.hits AS hits23, m0_.ip AS ip24, m0_.created_at AS created_at25, m0_.updated_at AS updated_at26 FROM milla_message m0_ INNER JOIN milla_currency m1_ ON m0_.currency_id = m1_.id INNER JOIN milla_category m2_ ON m0_.category_id = m2_.id INNER JOIN milla_region m3_ ON m0_.region_id = m3_.id INNER JOIN milla_city m4_ ON m0_.city_id = m4_.id WHERE m0_.status = 1 ORDER BY m0_.published DESC) dctrn_result LIMIT 20 OFFSET 0

source code
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php#L141

why SELECT DISTINCT %s FROM (%s) dctrn_result ???
why not SELECT DISTINCT m0_.id AS id0 FROM milla_message m0_ WHERE m0_.status = 1 ORDER BY m0_.published DESC LIMIT 20 OFFSET 0



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

Not a blocker

Comment by Marco Pivetta [ 31/Mar/13 ]

What's the result of `EXPLAIN` on a query without the subquery?

Comment by Sergey Gerdel [ 31/Mar/13 ]

explain without the subquery

Comment by Marco Pivetta [ 31/Mar/13 ]

Sergey Gerdel that's not the same query.

Comment by Marco Pivetta [ 31/Mar/13 ]

Sergey Gerdel this is still using

Using index; Using temporary; Using filesort

Check your indexes

Comment by Sergey Gerdel [ 31/Mar/13 ]

Not in the index problem

SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, m0_.title AS title1, m0_.text AS text2, m0_.price AS price3, m0_.originalPrice AS originalPrice4, m0_.condition_type AS condition_type5, m0_.image_1 AS image_16, m0_.image_2 AS image_27, m0_.image_3 AS image_38, m0_.image_4 AS image_49, m0_.image_5 AS image_510, m0_.video AS video11, m0_.contact_email AS contact_email12, m0_.contact_name AS contact_name13, m0_.contact_phone AS contact_phone14, m0_.contact_type AS contact_type15, m0_.published AS published16, m0_.type AS type17, m0_.status AS status18, m0_.highlight AS highlight19, m0_.urgent AS urgent20, m0_.topads AS topads21, m0_.period AS period22, m0_.hits AS hits23, m0_.ip AS ip24, m0_.created_at AS created_at25, m0_.updated_at AS updated_at26 FROM milla_message m0_ WHERE m0_.status = 1 ORDER BY m0_.published DESC) dctrn_result LIMIT 20 OFFSET 0

Time: 104.614s explain 3

SELECT DISTINCT m0_.id AS id0 FROM milla_message m0_ WHERE m0_.status = 1 ORDER BY m0_.published DESC LIMIT 20 OFFSET 0;

Time: 0.001s explain 4

Comment by Marco Pivetta [ 01/Apr/13 ]

Sergey Gerdel the ORM cannot simplify a complex query that way. There may be a conditional on one of the joined results, or generally usage of one of the joined results.

Things that could be optimized here are:

  • Removal of the `ORDER BY` clause when grouping (check ORM master, I think somebody already did that)
  • Trying to simplify the query by doing some serious hacking on the AST.

The problem I see here is that the chance to spawn random bugs because of the optimization is very high, and you'd have to rewrite `walkSelectStatement`

Comment by Marco Pivetta [ 01/Apr/13 ]

Marking as improvement

Comment by Sergey Gerdel [ 07/Apr/13 ]

Minor?
i have 100 sec for this query.
200k items are selected for temporary table. wtf?

OK. Programmers may be mistaken in parser
expect ORDER BY m0_.published DESC LIMIT 20 OFFSET 0) dctrn_result
Time: 0.001s

reality ORDER BY m0_.published DESC) dctrn_result LIMIT 20 OFFSET 0

Comment by Marco Pivetta [ 07/Apr/13 ]

Sergey Gerdel this problem does not introduce security issues and can be worked around by you while using your own pagination logic. It does not stop you from doing anything, that's why it's minor.

Comment by Sergey Gerdel [ 08/Apr/13 ]

ok)
i have already created my own paginator.
at last
please see how to fix this problem
https://github.com/Sergic/doctrine2/commit/2733c815387273d3bd199a68acb717e0cbc8ccfe

Comment by Tom Pryor [ 11/Oct/13 ]

I've also run into this problem which makes Doctrine's Paginator useless for large datasets. The actual query takes 0.002ms but the SELECT DISTINCT query doctrine executes takes over 30s because MySQL creates a temporary table with 200k+ records.

You don't need to remove the joined tables from the paginator query (I have conditions on the joined tables anyway), this has a negligible impact performance, but rather it is caused by SELECT DISTINCT and ORDER BY which no index configuration can solve. Rather, perhaps a flag could be added to the paginator to indicate my query does not fetch join any has many collections (i.e each row returned will be unique) negating the need for the SELECT DISTINCT. The pagination would only then need to perform the original query with LIMIT and OFFSET applied along with a separate COUNT query on the primary key, both of which are very fast as they'd use the indexes setup for the the original query.

Comment by Christophe Coevoet [ 11/Oct/13 ]

This flag already exists for the select query. See the second argument of the constructor.

For the count query, you should call $paginator->setUseOutputWalkers(false) to make it use a DQL AST walker instead of the SQL Output walker (the AST walker does not support counting on queries using HAVING which is why it is not selected by default)

Comment by Robert (Jamie) Munro [ 29/Nov/13 ]

I think this is more important than "minor", as I've experienced this when upgrading from 2.2. My site became unusably slow.

I can't easily work around it because I am using Symfony bundles that use this, I am not using this directly. None of the workarounds mentioned so far seem to have helped.





[DDC-2347] Refresh Uniqueidentifier ID from mssql of inserted Entity in doctrine2.3 Created: 13/Mar/13  Updated: 13/Mar/13

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

Type: Bug Priority: Minor
Reporter: Lucas Senn Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql
Environment:

Windows Server 2008 R2, Apache 2.2, Doctrine 2.3, PHP 5.4



 Description   

I don't want you to report something that isn't a bug.
But I read about problems with doctrine2 and mssql uniqueid's.
So First I asked a question at stackoverflow. No one could help me, and the only one who gave me a comment thought the same then me, that it looks like a bug.

If it isn't a bug I'm very sorry for this issue report.

Issue as reported in
http://stackoverflow.com/questions/15368082/refresh-uniqueidentifier-id-from-mssql-of-inserted-entity-in-doctrine2






[DDC-2338] Entity with composite foreign keys identifiers should be persisted after related entities without exception Created: 07/Mar/13  Updated: 07/Mar/13

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

Type: Improvement Priority: Minor
Reporter: Alessandro Tagliapietra Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: orm, unitofwork
Environment:

Mac OSX 10.8, php 5.4.11, doctrine git master version



 Description   

I've seen that when you create an entity with a composite foreign key as identifier it cannot be flushed until the related entities are already flushed to the database and not just persisted.

It would be nice to let the user flush all the entities together and just INSERT first the related entities to get the ID and then use that to INSERT the entity with composite foreign keys.

I'm going to create a pull request with the failing test.



 Comments   
Comment by Alessandro Tagliapietra [ 07/Mar/13 ]

Created pull request https://github.com/doctrine/doctrine2/pull/605





[DDC-2314] getResults with numeric indexes for fields Created: 22/Feb/13  Updated: 26/Feb/13

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

Type: Improvement Priority: Minor
Reporter: Ninj Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When executing a simple query with field names in SELECT clause, it is not possible to map field to numeric indexes.

This is an example that i would imagine to be useful:

SELECT c.id AS 0, c.name AS 1, l.text AS 2 FROM Category c LEFT JOIN c.label l

Thus, the resulting results could be numeric indexed array. It is useful for many situations: when working with an API which expects such arrays, or when using list to assign result fields to variables directly.

Query::HYDRATE_SCALAR does not achieve this, as one could think at first glance.






[DDC-2308] Naming Strategy for Reverse Engeneering Created: 21/Feb/13  Updated: 21/Feb/13

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

Type: Improvement Priority: Minor
Reporter: Andreas Prucha Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Unfortunately DatabaseDriver::getClassNameForTable() is declared as private method, which makes it quite difficult to change the naming strategy for reverse engeneering.

IMO this sould be declared protected. An even better way would be to extend the interface of the Naming Strategy objects to support the reverse direction:

classToTableName -> tableToClassName
propertyToColumnName -> columnToPropertyName.

This way we would have a consistent name-mapping






[DDC-2301] Support inheritance in ResultSetMappingBuilder Created: 16/Feb/13  Updated: 16/Feb/13

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

Type: Improvement Priority: Minor
Reporter: Ross Masters Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: nativesql, resultsetmapping


 Description   

ResultSetMappingBuilder does not support inherited fields. For example, calling ResultSetMappingBuilder::addRootEntityFromClassMetadata($class, $alias) throws an exception to say this.

I was wondering if there were any reasons as to why this would be difficult to implement? I haven't had an extensive look at Doctrine's source but it feels like this has been not implemented on purpose.

Thanks






[DDC-2288] Schema Tool doesn't update collation on table level Created: 08/Feb/13  Updated: 08/Feb/13

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

Type: Improvement Priority: Minor
Reporter: Rickard Andersson Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: collation, schematool


 Description   

In Symfony2, when updating the collation option of a table, the schema tool doesn't recognize the change:

Changing from:

 
* @ORM\Table()

To:

 
* @ORM\Table(options={"collate"="utf8_swedish_ci"})

Results in:

 
$ php app/console doctrine:schema:update --dump-sql
Nothing to update - your database is already in sync with the current entity metadata.





[DDC-2287] Getter/Setter: generate "isEnabled()" instead of "getEnabled()" for boolean field in entity classes Created: 08/Feb/13  Updated: 26/Feb/13

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

Type: Improvement Priority: Minor
Reporter: Sukhrob Khakimov Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It would be better if doctrine generated "isEnabled()" instead of "getEnabled()" for boolean field in entity classes. Because, it is more meaningful.



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

Not sure this kind of check should be handled. Starting to add all this kind of rules makes me think that it is becoming a big ball of mud





[DDC-2286] Update documentation for collation Created: 08/Feb/13  Updated: 08/Feb/13

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

Type: Documentation Priority: Minor
Reporter: Rickard Andersson Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: collation, documentation


 Description   

The documentation at http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/faq.html#how-do-i-set-the-charset-and-collation-for-mysql-tables clearly states that the collation should be set at database level and then inherited for all tables created.

Digging through the code and reading this issue http://www.doctrine-project.org/jira/browse/DDC-2139 it's clear that this is no longer the case.






[DDC-2283] Paginator with orderBy in joined data retrieve bad result Created: 07/Feb/13  Updated: 26/Feb/13

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

Type: Improvement Priority: Minor
Reporter: Jean-Philippe THEVENOUX Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: paginator


 Description   

entity A have many entity B

If DQL is something like "select A, B from A join B order by A.field1, B.field2"
Then Paginator retrieve different Id by a query like :
"select distinct a.id, a.field1, b.field2 from ( ....) order by a.field1 ASC , b.field2 ASC limit 15 offset 0"

so, if a entity A have 20 entity B (and these sub-entity have all a different b.field2) then there's only 1 A retrieved






[DDC-2281] Validation against database-first generated xml requires that the column order within a composite primary key match the order the columns are in in mapping xml Created: 06/Feb/13  Updated: 09/May/13

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

Type: Bug Priority: Minor
Reporter: Aaron Moore Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In using a database-first approach utilizing orm:convert-mapping to generate xml, the validation and schema-tool reports that my composite primary key (ex. Columns A, C, B) be dropped and added in the order in which the mapping appears in the xml (ex. Columns A, B, C).

These columns are not auto-increment and are simply a mixture of int and varchar.



 Comments   
Comment by Benjamin Eberlei [ 09/May/13 ]

Is the composite key a mix of association and field types?

Comment by Aaron Moore [ 09/May/13 ]

I'm trying to remember the usage as it was a short term project but I believe it is.

For example a user has a userid.

The table in question might have a primary key consisting of the userid and an int representing a year..





[DDC-2260] Partial DQL query doesn't respect given order of columns Created: 26/Jan/13  Updated: 27/Jan/13

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

Type: Improvement Priority: Minor
Reporter: Alexander Grimalovsky Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When executing partial DQL queries it may be important to keep given order of columns e.g. for "pairs" hydrator when first column of a pair is used as a key and second - as value. For example query like this:

select partial u.{id,name} from my:User u

will expect "id" to be first in resulted set and "name" to be second and not vice versa.

However Doctrine parses this part of statement via iterating over fields mapping from entity's class metadata (as can be seen in Doctrine\ORM\Query\SqlWalker::walkSelectExpression()):

foreach ($class->fieldMappings as $fieldName => $mapping) {
  if ($partialFieldSet && ! in_array($fieldName, $partialFieldSet)) {
    continue;
  }
  ...

and hence given columns order preserving is not guaranteed.



 Comments   
Comment by Marco Pivetta [ 26/Jan/13 ]

What is the advantage in respecting the order given in the DQL query?

Comment by Alexander Grimalovsky [ 27/Jan/13 ]

Currently the only practical reason for it that I found is "pairs" hydrator. However it is, of course, possible to implement it without such change too.

Generally speaking this behavior (getting result set with same order of columns that was given in a query) is something that is feeling "natural" for operations with database since it is how you normally get results from SQL queries.

Maybe it will be enough to mention in documentation for Doctrine that given columns order is not guaranteed to be kept.

Comment by Marco Pivetta [ 27/Jan/13 ]

@Alexander Grimalovsky I don't think it's worth mentioning it. Also, including a fix for this is quite complex. If you prefer to document it, go for it!





[DDC-2236] SUM(..) with Pagination gives incorrect result Created: 11/Jan/13  Updated: 10/Feb/13

Status: In Progress
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.2.3
Fix Version/s: None

Type: Documentation Priority: Minor
Reporter: Oleg Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: paginator
Environment:

Linux



 Description   

https://github.com/whiteoctober/Pagerfanta/issues/69

<?php
$query = $em->getRepository('M\E\Q')
->createQueryBuilder('q')
->select('q', 'SUM(q.price) AS amount')
->where('q.id IN(19, 20, 22)')
->groupBy('q.customer')
;

$pager = new Pagerfanta(new DoctrineORMAdapter($query));
$pager->setMaxPerPage(30);
$pager->setCurrentPage($request->query->get('page', 1));

$result = $pager->getCurrentPageResults();
print_r($result[0]['amount']); // 156.71 - Incorrect

$result = $query->getQuery()->getResult();
print_r($result[0]['amount']); // 553.47
?>

Sql for the above:

SELECT DISTINCT id0 FROM (SELECT q0_.id AS id0, SUM(q0_.price) AS sclr36 FROM Q q0_ WHERE q0_.id IN (19, 20, 22) GROUP BY q0_.customer_id) dctrn_result LIMIT 30 OFFSET 0
SELECT q0_.id AS id0, SUM(q0_.price) AS sclr36 FROM Q q0_ WHERE q0_.id IN (19, 20, 22) AND q0_.id IN ('19') GROUP BY q0_.customer_id
SELECT q0_.id AS id21, SUM(q0_.price) AS sclr36 FROM Q q0_ WHERE q0_.id IN (19, 20, 22) GROUP BY q0_.customer_id

Sql with fetchJoin = false (new DoctrineORMAdapter($query, false))

SELECT q0_.id AS id0, SUM(q0_.price) AS sclr36 FROM Quote q0_ WHERE q0_.id IN (19, 20, 22) GROUP BY q0_.customer_id LIMIT 30 OFFSET 0
SELECT q0_.id AS id0, SUM(q0_.price) AS sclr36 FROM Quote q0_ WHERE q0_.id IN (19, 20, 22) GROUP BY q0_.customer_id



 Comments   
Comment by Alexander [ 09/Feb/13 ]

Can you also test this with doctrine >= 2.3? The pagination code changed quite a lot.

Comment by Oleg [ 10/Feb/13 ]

Looks like no change

composer.json:
"doctrine/orm": "2.3.*",

php composer.phar update
Loading composer repositories with package information
Updating dependencies

  • Installing doctrine/common (2.3.0)
    Loading from cache
  • Installing doctrine/dbal (2.3.2)
    Loading from cache

then cleared cache but result is same
Here's the code

 
$query = $this->getDoctrine()->getEntityManager()->getRepository('MyBundle:Invoice')
  ->createQueryBuilder('q')
  ->select('q', 'SUM(q.amount) AS amount')
  ->groupBy('q.customer')
;
 
95 Connect	root@localhost on **
95 Query	SELECT DISTINCT id0 FROM (SELECT i0_.id AS id0, i0_.invoice_num AS invoice_num1, i0_.date AS date2, i0_.amount AS amount3, i0_.vat_amount AS vat_amount4, i0_.amount_paid AS amount_paid5, i0_.md5 AS md56, i0_.is_exported AS is_exported7, i0_.created AS created8, SUM(i0_.amount) AS sclr9 FROM Invoice i0_ GROUP BY i0_.customer_id) dctrn_result LIMIT 30 OFFSET 0
95 Query	SELECT i0_.id AS id0, i0_.invoice_num AS invoice_num1, i0_.date AS date2, i0_.amount AS amount3, i0_.vat_amount AS vat_amount4, i0_.amount_paid AS amount_paid5, i0_.md5 AS md56, i0_.is_exported AS is_exported7, i0_.created AS created8, SUM(i0_.amount) AS sclr9, i0_.customer_id AS customer_id10 FROM Invoice i0_ WHERE i0_.id IN ('2') GROUP BY i0_.customer_id
95 Query	SELECT i0_.id AS id0, i0_.invoice_num AS invoice_num1, i0_.date AS date2, i0_.amount AS amount3, i0_.vat_amount AS vat_amount4, i0_.amount_paid AS amount_paid5, i0_.md5 AS md56, i0_.is_exported AS is_exported7, i0_.created AS created8, SUM(i0_.amount) AS sclr9, i0_.customer_id AS customer_id10 FROM Invoice i0_ GROUP BY i0_.customer_id
130210 16:08:25	   95 Quit	

But I understand why that happens, it's due to group by and pagination nature.
The first query returns only one row with id "2", second query should be actually "..WHERE i0_.id IN ('2', '3', '4')"

If I do

$pager = new Pagerfanta(new DoctrineORMAdapter($query, false));

I get this sql

SELECT i0_.id AS id0, i0_.invoice_num AS invoice_num1, i0_.date AS date2, i0_.amount AS amount3, i0_.vat_amount AS vat_amount4, i0_.amount_paid AS amount_paid5, i0_.md5 AS md56, i0_.is_exported AS is_exported7, i0_.created AS created8, SUM(i0_.amount) AS sclr9, i0_.customer_id AS customer_id10 FROM Invoice i0_ LIMIT 30 OFFSET 0

I think it should be noted somewhere that if you do groupBy you should set fetchJoin to false?

Comment by Marco Pivetta [ 10/Feb/13 ]

Updating to Documentation issue.





[DDC-2227] Add details about developer being responsible of inverse side of an association Created: 09/Jan/13  Updated: 09/Jan/13

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

Type: Documentation Priority: Minor
Reporter: Marco Pivetta Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: None


 Description   

As far as I know, docs don't explain that it is up to the developer to keep the object graph consistent instead of relying on Doctrine ORM for everything.

For example, for many to many, examples like following may be used:
https://gist.github.com/3121916






[DDC-2203] add EntityManager->getFilters()->isEnabled('filterName'') Created: 17/Dec/12  Updated: 07/Sep/13

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

Type: Improvement Priority: Minor
Reporter: Enea Bette Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Comments   
Comment by Paweł Nowak [ 10/Jan/13 ]

My pull request (https://github.com/doctrine/doctrine2/pull/548) contains an implementation of the method. Note that no exception is thrown if you query for the state of a non-existing filter - in such a case, false is returned as for disabled filters.





[DDC-2200] Duplicates returned while accessing associations from @PostPersist callback Created: 15/Dec/12  Updated: 15/Dec/12

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

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


 Description   

When creating a new Post and adding it to a collection in an existing Thread (i.e. loaded from the database), referencing Thread's posts collection in Post's @PostPersist callback returns the Post twice. To clarify, this only happens when Thread was previously persisted. If I'm creating a new Thread object the code works as expected. I've included some sample code to better illustrate my issue.

I don't know if this is a bug, or if I'm doing something that I shouldn't be, but I couldn't find this limitation mentioned in the documentation, and this seems to go against the expected behavior.

Here are my sample entities:


/**
 * @Entity
 * @Table(name="thread")
 */
class Thread
{
    /** 
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    protected $id;

    /** 
     * @OneToMany(targetEntity="Post", mappedBy="thread", cascade={"persist", "remove"})
     */
    protected $posts;

    public function __construct() {
        $this->posts = new ArrayCollection();
    }   

    public function getPosts() {
        return $this->posts->toArray();
    }   

    public function addPost(Post $post) {
        $post->setThread($this);
        $this->posts->add($post);
    }   
}

/**
 * @Entity
 * @Table(name="post")
 * @HasLifecycleCallbacks
 */
class Post
{
    /** 
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    protected $id;

    /** 
     * @ManyToOne(targetEntity="Thread", inversedBy="posts")
     * @JoinColumn(name="thread_id", referencedColumnName="id")
     */
    protected $thread;

    public function getId() {
        return $this->id;
    }   

    /** 
     * @PostPersist
     */
    public function onPostPersist() {
        $posts = $this->thread->getPosts();
        foreach ($posts as $post) {
            echo 'id: ' . $post->getId() . ' type: ' . get_class($alert) . '<br />';
        }   
    }

    public function setThread(Thread $thread) {
        $this->thread = $thread;
    }   
}

And the calling code:


// Grab an existing thread.
$thread = $em->getReference('Thread', 1); 
$thread->addPost(new Post());
$em->flush();

This outputs:


id: 1 type: Post
id: 1 type: Post

Alternatively:


// Create a new thread.
$thread = new Thread()
$thread->addPost(new Post());
$em->persist($thread);
$em->flush();

This outputs:


id: 1 type: Post






[DDC-2164] Extend the cache support to eAccelerator Created: 23/Nov/12  Updated: 26/Nov/12

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

Type: Improvement Priority: Minor
Reporter: Enea Bette Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: cache, drivers


 Description   

It would be nice if the Doctrine caching drivers would support the eAccelerator library.



 Comments   
Comment by Marco Pivetta [ 23/Nov/12 ]

Enea Bette eAccelerator is known for being stripping comments from cached source (making it impossible to use annotations)... Do you happen to know if this is fixed? Supporting it as cache driver is fine btw, I just wonder how many users will start thinking of using eAccelerator and then will be facing this huge limitation.

Comment by Enea Bette [ 26/Nov/12 ]

I know that eAccelerator has this issue. It would be nice if we could utilize it with XML, YML and PHP based mapping though.
Do you know if the same problem would appear with these kinds of mapping strategies?

To give response to your question (eAccelerator and annotations incompatibility), there is a pull request on github, https://github.com/eaccelerator/eaccelerator/issues/19 .

It seems that in the future these could be resolved, and at that time it would be very nice to have that supported with doctrine (symfony2 already has support for this library).

"I just wonder how many users will start thinking of using eAccelerator and then will be facing this huge limitation". Sometimes users just does not have a choice. Imagine the case when you have a hosted site that requires caching functionalities and the only available cache library is eAccelerator (as just in my case). You would be fried as a chicken hehe





[DDC-2140] [GH-512] Added addParameters() to Query and QueryBuilder Created: 13/Nov/12  Updated: 08/Feb/14

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

Type: Improvement Priority: Minor
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: Query,, QueryBuilder
Environment:

OS X 10.8.2, PHP 5.3.18, Nginx 1.2.4 (php through FPM)



 Description   

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

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

Message:

This method behaves like setParameters() before version 2.3:
It will add new parameters to the collection, and override any existing positions/names.

It can take a Doctrine\Common\Collections\ArrayCollection with Doctrine\ORM\Query\Parameter objects, as well as a plain array with key/value pairs, as argument.

This will greatly ease the upgrade to Doctrine 2.3, because you only need to perform a project-wide replace of setParameters with addParameters, in stead of going into your code and determine if calls to setParameters are ok or need refactoring.

I've also added unit-tests to maintain integrity.



 Comments   
Comment by Benjamin Eberlei [ 20/Nov/12 ]

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

Comment by Jasper N. Brouwer [ 20/Nov/12 ]

I don't feel strong need to have such an API.
If you want to keep track and merge collection of parameters, all you have to do is create an array (or an ArrayCollection), manipulate the instance and then setParameters at the end.
Unless you give me a stronger argument, this code won't be in. Closing for now.

Hi Guilherme,

I agree that such a method makes less sense in Query, because when you write a DQL string all parameters are known at once. But when using the QueryBuilder you might need different parameters in different cases, so addParameters() becomes useful there.

I guess it's just a convenience method, like IMHO setParameter() is. (You could just do $qb->getParameters()->add())

The main reason for adding the method was, like I said, upgrading to Doctrine 2.3. I've already upgraded all my projects to Doctrine 2.3, so the method is less useful for me now. But it took me a full day to refactor my repositories, because there is no safe way to automate the process. A simple search-and-replace setParameters() to addParameters() would have taken me 5 minutes

I'm content with your decision.
If others find addParameters() useful, I hope they let us know.

Comment by Doctrine Bot [ 08/Feb/14 ]

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





[DDC-2134] Add referential integrity check for MySQL to console commands Created: 09/Nov/12  Updated: 09/Nov/12

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

Type: New Feature Priority: Minor
Reporter: Menno Holtkamp Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

MySQL



 Description   

Today I spent some time solving a PHP 'White Screen of Death'. I traced it back to a Entity of which the proxy's __load() function was invoked because af a EXTRA_LAZY association. Due to incorrect database contents (the entry ID was changed due to an update: referential integrity broke), the __load() query resulted in no results. The EntityNotFoundException did for some reason not show up in our logs, probably because the lazy load was triggered by a magic __toString() function.

The cause is because of the way we populate or tables with domain data:

SET FOREIGN_KEY_CHECKS = 0;
#IMPORT STUFF from CSV
SET FOREIGN_KEY_CHECKS = 1;

MySQL does not trigger any errors when the foreign key checks are turned back on, leaving the table in an inconsistent state.

To prevent this, I found some information in this post: http://www.mysqlperformanceblog.com/2011/11/18/eventual-consistency-in-mysql/, which I used to come with the following queries

#Check the constraints of a specific database
SELECT *
	FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
		WHERE TABLE_SCHEMA = 'databaseName'
		AND REFERENCED_TABLE_NAME IS NOT NULL

#Generate table specific queries to find orphaned entries
SELECT CONCAT(
	 'SELECT ', GROUP_CONCAT(DISTINCT CONCAT(K.CONSTRAINT_NAME, '.', P.COLUMN_NAME,
	  ' AS `', P.TABLE_SCHEMA, '.', P.TABLE_NAME, '.', P.COLUMN_NAME, '`') ORDER BY P.ORDINAL_POSITION), ' ',
	 	'FROM ', K.TABLE_SCHEMA, '.', K.TABLE_NAME, ' AS ', K.CONSTRAINT_NAME, ' ',
	 		'LEFT OUTER JOIN ', K.REFERENCED_TABLE_SCHEMA, '.', K.REFERENCED_TABLE_NAME, ' AS ', K.REFERENCED_TABLE_NAME, ' ',
	 		' ON (', GROUP_CONCAT(CONCAT(K.CONSTRAINT_NAME, '.', K.COLUMN_NAME) ORDER BY K.ORDINAL_POSITION),
	 		') = (', GROUP_CONCAT(CONCAT(K.REFERENCED_TABLE_NAME, '.', K.REFERENCED_COLUMN_NAME) ORDER BY K.ORDINAL_POSITION), ') ',
	 		'WHERE ', K.REFERENCED_TABLE_NAME, '.', K.REFERENCED_COLUMN_NAME, ' IS NULL;'
	  )
    INTO OUTFILE '/tmp/verifyDatabaseTableIntegrity.sql'
    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE K
      INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE P
        ON (K.TABLE_SCHEMA, K.TABLE_NAME) = (P.TABLE_SCHEMA, P.TABLE_NAME)
        AND P.CONSTRAINT_NAME = 'PRIMARY'
    WHERE K.TABLE_SCHEMA = 'databaseName'
      AND K.REFERENCED_TABLE_NAME IS NOT NULL
      GROUP BY K.CONSTRAINT_NAME;
	

By running the generated queries, we can now easily find the records that break referential integrity.

It might be an idea of adding this functionality to the orm:validate-schema, or a new orm:validate-database-integrity?






[DDC-2103] Add support for using AliasResultVariable in WhereClause Created: 25/Oct/12  Updated: 25/Oct/12

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

Type: New Feature Priority: Minor
Reporter: Martin Hasoň Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

It would be nice if supported writing in DQL:

SELECT LOWER(a.name) AS name FROM User a WHERE name LIKE ?

The resulting sql:

SELECT LOWER(c0_.name) AS sclr0 FROM users c0_ WHERE LOWER(c0_.name) LIKE ?






[DDC-2076] Optimization for MEMBER OF Created: 14/Oct/12  Updated: 14/Oct/12

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

Type: Improvement Priority: Minor
Reporter: Christophe Coevoet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql


 Description   

Currently, using MEMBER OF for a ManyToMany collection does a join on the table of the related entity, whereas all it needs is in the join table.

Using the following DQL:

SELECT p FROM Player p
WHERE NOT :team MEMBER OF p.targetedBy

Here is the current generated SQL:

WHERE NOT EXISTS (SELECT 1 FROM player_team p1_ INNER JOIN Team t2_ ON p1_.team_id = t2_.id WHERE p1_.player_id = p0_.id AND t2_.id = ?)

whereas it could drop the join:

WHERE NOT EXISTS (SELECT 1 FROM player_team p1_ WHERE p1_.player_id = p0_.id AND p1_.team_id = ?)





[DDC-2053] [GH-460] added support to extend strategies for IdGenerators Created: 02/Oct/12  Updated: 22/Dec/13

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

Type: Improvement Priority: Minor
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 Powerhamster:

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

Message:

Mapping drivers now use extended classmetadata class to find constants of generator types.
Method completeIdGeneratorMapping is now protected and can be extended



 Comments   
Comment by Benjamin Eberlei [ 03/Oct/12 ]

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

Comment by Doctrine Bot [ 22/Dec/13 ]

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





[DDC-2035] XML Mapping : add attribute "length" for tag "id" Created: 20/Sep/12  Updated: 29/Sep/12

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

Type: New Feature Priority: Minor
Reporter: Erik Müller Assignee: Fabio B. Silva
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux, Doctrine ORM 2.3.0, MySQL



 Description   

XML mapping :

<id name="id" type="string" length="16"/>

Generate SQL :

id varchar(255) not null

It's not possible with XML mapping to have :

 id varchar(16) not null

Because tag "id" doesn't support "length" attribute.
Please add this attribute



 Comments   
Comment by Fabio B. Silva [ 20/Sep/12 ]

Hi Erik,

The atribute "id" arealdy support "length" in the current doctrine version
: https://github.com/doctrine/doctrine2/blob/2.3/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php#L259

Which version are you using ?





[DDC-2030] better way to detect class parents Created: 13/Sep/12  Updated: 13/Sep/12

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

Type: Improvement Priority: Minor
Reporter: Asmir Mustafic Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi!
Currently i'm heavy using doctrine to generate entities starting form database schema (aprox 500 tables with thousand of relations).

I'm trying to detect some inheritance cases, but there is a problem.

Doctrine always uses PHP class inheritance to detect entity hierarchy, but generating entities starting from database, i have not yet any php class.

There is a better way to detect entities hierarchy? Without php classes...
Mapping files should be self-sufficient, even without php files.

The practical case is:
in DatabaseDriver i'm trying to call $metadata->addDiscriminatorMapClass($name, $className) method, but it raises an exception if $classNam does not exists.

Even if i manualy create XML mapping files, and then i try to generate php entityes. There is the same problem. XmlDriver tries to call setDiscriminatorMap method that raises the same exception.






[DDC-1993] New method required: ClassMetadataInfo::isAssociationNullable() Created: 22/Aug/12  Updated: 22/Aug/12

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

Type: Improvement Priority: Minor
Reporter: gregoire_m Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi,

I'm working with Symfony 2.1, and I need to know if an association is nullable for a given entity (to know if a form field should be marked as 'required'). So I'd like to have a isAssociationNullable() method in the ClassMetadataInfo class, that should do the same thing that the isNullable() method does for fields.

You can see more information about the problem on the Symfony issue.

Thanks.






[DDC-1988] Add Any and ManyToAny annotations Created: 18/Aug/12  Updated: 10/Jul/14

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

Type: New Feature Priority: Minor
Reporter: Stefano Rodriguez Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

It would be really nice to have @Any and @ManyToAny relations/annotations implemented like on Hibernate.
http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/annotations/ManyToAny.html
Right now I've implemented these in a Symfony2 bundle (that I'd be happy to share once it's ready and a bit documented), using listeners on postLoad, preFlush and prePersist
However I think this is a very common use case that anyone will encounter at least once/twice in every middle/big-sized project, and for this reason I think this should be implemented as a core feature.






[DDC-1983] Incorrect use statement in 25.1.3. Configuration example (Doctrine Console) Created: 15/Aug/12  Updated: 15/Aug/12

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

Type: Documentation Priority: Minor
Reporter: Atli Thor Jonsson Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: Cli, documentation


 Description   

The code example here:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/tools.html#configuration-non-pear

In the second "use" statement it references a "EntityManagerHelper" from the "Doctrine\DBAL\Tools\Console\Helper\" package. However, it does not exist there. It does exist in the "Doctrine\ORM\Tools\Console\Helper\" package though, and replacing it seems to work.






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

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

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


 Description   

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

"tableAlias.column = '$filterParameter'"

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

"tableAlias.state = 1"

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

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

to eventually result in:

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

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

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






[DDC-1950] Useful exception when combining Column with ManyToOne Created: 26/Jul/12  Updated: 26/Jul/12

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

Type: Improvement Priority: Minor
Reporter: Igor Wiedler Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When applying both @Column and @ManyToOne annotations to a field, it blows up with crazy internal errors. It would be great if this case – and similar cases – could throw a nice exception which tells the user what he did wrong.






[DDC-1921] Clarify Identifier definition for CTI entities Created: 11/Jul/12  Updated: 11/Jul/12

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

Type: Documentation Priority: Minor
Reporter: Ludek Stepan Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hello,

Reference Guide topic 4.8 Identifers/Primary Keys(http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#identifiers-primary-keys) states that: "Every entity class needs an identifier/primary key."

However, example in topic 7.3. Class Table Inheritance (http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/inheritance-mapping.html#class-table-inheritance) doesn't contain any definitions for Ids.

Consider following code:

/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"})
 */
class Person
{
    /** @Id @Column(type="integer") */
    private $id;

    public function getId() {
        return $this->id;
    }
}

/** @Entity */
class Employee extends Person
{
    /** @Id @Column(type="integer") */
    private $id;

    // Overrides parent to retrieve private
    public function getId() {
        return $this->id;
    }
}

// create instances and $em->persist(...)

// $person instanceof Person
$person->getId(); // Returns id.

// $employee instanceof Employee
$employee->getId(); // Returns null. Private $id in subclass isn't assigned.

Please clarify correct use of identifiers in CTI subclass entities. Should subclasses contain any definitions of identifiers?

Thank you!

Ludek






[DDC-1916] Centralize the Cache mechanism simplifying the query creation Created: 09/Jul/12  Updated: 09/Jul/12

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

Type: New Feature Priority: Minor
Reporter: liuggio Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi all,

in a big project if you have queries spread out in different
repositories,
when you have to modify a cache lifetime, you have to search the query and
modify the code, than test it.
Is not so easy also to answer to 'how much is the cache for the query XYZ?'

the idea:
Each group of repository (bundle) should have in a single point maybe into its config file a place where you could set the lifetime of the various queries.

see the code for a better explanation
https://gist.github.com/3075742

the pro: a better handling of the cache mechanism
cons: ?

Do you think is a good approach?
Have you ever had a similar problem?

Thanks

liuggio






[DDC-1889] generate persisters Created: 21/Jun/12  Updated: 22/Oct/12

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

Type: New Feature Priority: Minor
Reporter: Fabio B. Silva Assignee: Fabio B. Silva
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I'm not sure if this is really possible..

but to improve performance we should consider generate custom entity persisters.

Now entity persister are not cached,
if we generate it, we can create performance improvement in hidrators, avoiding checks and sql generation every time that an persister is called.



 Comments   
Comment by Benjamin Eberlei [ 21/Jun/12 ]

This should be relatively easy in the first step by ust generate the RSM and SQL statements in the constructor and extending from the default persister.





[DDC-1888] generate hydrators Created: 21/Jun/12  Updated: 21/Jun/12

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

Type: New Feature Priority: Minor
Reporter: Fabio B. Silva Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

To improve performance we should consider generate custom hydrators per entity or per rsm.

I think that will create a huge performance improvement, avoiding checks every time that an entity/result is hydrated.






[DDC-1847] Do not check for type equality in scalars when computing changeset? Created: 30/May/12  Updated: 08/Jun/12

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

Type: Improvement Priority: Minor
Reporter: Albert Casademont Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Decimal type in mysql converts as a string in php. This is great as Decimal has a much higher precision than a float or double and that precision would be lost if converted to a float in PHP. Fine! But when doing calculations (as my numbers do not require an enormous precision gmp_ functions are not necessary) php converts these strings into floats. Then, when computing the changeset, as the value is compared with === is marked as a change even though there is none ("5.00" string vs 5.00 float) and an UPDATE for that row is made. Would it be possible to check only for simple equality "==" instead of type equality "===" when dealing with scalar types?

Another example of this would be the boolean type, that it is stored as an integer 1 in mysql but converted to a boolean true in php. If during the execution of my code that boolean gets converted to an integer 1, that will trigger an UPDATE also because 1 !== true.

Should this be my responsability or doctrine should be a little more flexible regarding comparisons? Thanks!!



 Comments   
Comment by Marco Pivetta [ 08/Jun/12 ]

Hi there!
Actually, doctrine orm converts floats from DB string to double at https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Types/FloatType.php#L52 . Keeping the correct type in for your fields is up to you, so be sure to cast in every setter

Comment by Albert Casademont [ 08/Jun/12 ]

Hi marco!

Actually i am using DECIMAL (or NUMERIC), not FLOAT, That type is not casted as it would lose precision. Therefore, my problem is when working with DECIMAL (Which is, btw, the type that mysql recommends for storing money values)
thet
https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Types/DecimalType.php

Comment by Marco Pivetta [ 08/Jun/12 ]

Unsure if the cast should happen in the type (just ignorant about the implication in precision), but I'll suggest it then.

Comment by Albert Casademont [ 08/Jun/12 ]

It should not happen as the DECIMAL type in MySQL has much more precision than a double or float in PHP. It was previously cast but there was an issue regarding this cast and the cast was deleted

http://www.doctrine-project.org/jira/browse/DBAL-121

After that, in another issue a user points out the same problem i am facing, that i have to cast back to string if i do not want doctrine to issue an UPDATE command for values that have not changed

http://www.doctrine-project.org/jira/browse/DBAL-180

As i said, my only point is that maybe, when computing the changeset, the comparison for scalar types should be more relaxed with a == instead of a ===

Comment by Marco Pivetta [ 08/Jun/12 ]

Don't think this can be done, as you don't really know what types (and so also the conversion rules) the user applies to his own model. I wouldn't do that, leaving the implementor of the entities to have strict checks on types during operations in setters...





[DDC-1819] Allow ResultSetMapping to be used for objects that are not entities Created: 11/May/12  Updated: 14/May/12

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

Type: Improvement Priority: Minor
Reporter: Marijn Huizendveld Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently Doctrine\ORM\Query\ResultSetMapping can only be used to query the database for entities using the EntityManager::createNativeQuery method. It would be great if we could use this as well for objects that are not entities. That way we can create simple DTO's and map them to a query using the ResultSetMapping.

I'll open a PR If there are no objections.



 Comments   
Comment by Benjamin Eberlei [ 11/May/12 ]

Good idea. You could make this happen by adding a ArbitraryObjectHydrator that does not use the ClassMetadata but creates ReflectionProperty instances during the hydration.

Api would then be:

$rsm = new ResultSetMapping();
....

$query = $em->createNativeQuery($sql, $rsm);
$objects = $query->getResult(Query::HYDRATOR_ARBITRARY_OBJECTS);
Comment by Marijn Huizendveld [ 13/May/12 ]

Thanks for your input. I'll try to work on some tests this week.

Comment by Marijn Huizendveld [ 14/May/12 ]

I've started working on the test suite in this PR.





[DDC-1754] Allow use of Foregin Keys in DQL LIKE condition Created: 03/Apr/12  Updated: 09/Apr/12

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

Type: Improvement Priority: Minor
Reporter: Tim Roediger Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Php 5.3



 Description   

When using a LIKE condition in a WHERE clause, I would like to be able to use the foreign key of a single value association. For example:

Imagine Product and Department are both entities. Department has the field Name with a unique index. Product is has a ManyToOne association called Department with the Department entity, referencing the field Name.

I would like to write:
SELECT FROM Product p WHERE p.Department LIKE '% Tools'

However, at present I need to write:
SELECT FROM Product p
JOIN p.Department d
WHERE d.name LIKE '% Tools'

The issue is one of performance. On large record sets the first query runs several magnatudes more quickly than the second, particularly when four or five joins are involved.

Looking at the DQL grammar from the online docs, the relveant lines are:

LikeExpression ::= StringExpression ["NOT"] "LIKE" string ["ESCAPE" char]
StringExpression ::= StringPrimary | "(" Subselect ")"
StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression

The problem is the StateFieldPathExpression in StringPrimary. When used with a LikeExpression a SingleValuedAssociationField should be allowed also.



 Comments   
Comment by Benjamin Eberlei [ 07/Apr/12 ]

This would only work if Department#Name is the primary key. Is it?

DQL is not about optimized performance in very single edge case. We need to keep some parts open to keep the code simple. This is at best a feature request, not a bug.

Comment by Tim Roediger [ 09/Apr/12 ]

Thanks for your reply Benjamin,

I agree with your assesment that this is more accurately an improvement request than a bug. My appologies it was placed in the wrong category.

No, Department#Name is not the primary key, but it does have a unique index.

I've worked a little more to understand the DQL grammar. It appears that only one small, simple change is required:

FROM:
StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression

TO:
StringPrimary ::= SingleValuedPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression

This would improve consistancy with other aspects of DQL. For example, AggregateExpression COUNT, NullComparisonExpression , GroupByItem, and ArithmeticPrimary all allow a SingleValuedPathExpression rather than the more strict StateFieldPathExpression.

Bascially my frustration is that as DQL currently stands, foregin keys which are already existant in a db table cannot be used in a LIKE expression without doing an unnessessary JOIN. Foreign keys can already be used in DQL for BETWEEN, IS NULL and comparison expressions, so why not LIKE expressions also? It appears the only thing holding this back is an unrequired restriction in the DQL grammar.

Cheers, Tim





[DDC-1716] Better unique constraints handling or even updateIfExists/findOneOrCreate Created: 19/Mar/12  Updated: 19/Apr/12

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

Type: New Feature Priority: Minor
Reporter: Konstantin Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 6
Labels: None


 Description   

It is too hard handle rows duplication now. As adviced here http://stackoverflow.com/questions/3967226/checking-for-duplicate-keys-with-doctrine-2 we should catch \PDOException with code 23000. This is bad behavior.

So I propose:
a. Add DuplicateRowException wich will throwed by flush method (maybe wrapped PDOException) with method "getDuplicatedProperties" (based on sql error description parsing + mapping)
b. Add method findOneOrCreate (hello, Propel!) or updateIfExists to ObjectInterface, EntityManager
c. Combine a, b



 Comments   
Comment by Mark van der Velden [ 19/Apr/12 ]

I don't think it should be limited to the flush method, however, as this can occur with "custom" queries also. It would be ideal if the errors being generated can be much more easily (read: standardized) caught or read.

I'm in favor of letting the database handle integrity checks, and not run a query to decide wether or not the update or insert queries will violate. Hence the desire to handle this more gracefully.

Comment by Lucas van Lierop [ 19/Apr/12 ]

The DBAL statement class (https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Statement.php) has and execute method which might be a good place to catch and convert the generic PDOExceptions by wrapping the line

$stmt = $this->stmt->execute($params);

in a try/catch statement which then calls some kind of PDOException to Doctrine Exception method





[DDC-1675] PDO::FETCH_GROUP Created: 01/Mar/12  Updated: 01/Mar/12

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

Type: New Feature Priority: Minor
Reporter: Henrik Bjornskov Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

PDO supports grouping by a field when doing a fetchAll() by using PDO::FETCH_GROUP. This can in many places be useful. http://blog.stealth35.com/2011/08/17/pdo-fetch-group.html desribes the behavior quite well.






[DDC-1630] Get PersistentCollection::getDeleteDiff is empty when collection changes from 1 item to zero items Created: 31/Jan/12  Updated: 09/Feb/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: Minor
Reporter: Lee Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 2
Labels: None
Environment:

Symfony2


Attachments: File DDC1630Test.php    

 Comments   
Comment by Steve Müller [ 09/Feb/12 ]

Same problem here. I wanted to write some unit tests, checking the entity relations and ran into exactly the same problem. Maybe my code can provide some more information (Group entity is the owning side, role entity is the inverse side):

WHAT DOES NOT WORK:

        /**
         * Test ArrayCollection
         */
        $group = new Group('Group Test');
        $em->persist($group);
        $em->flush();

        $groups = new ArrayCollection();
        $groups->add($group);

        $this->role->setGroups($groups);

        $this->assertEquals($groups, $this->role->getGroups());

        /**
         * Test PersistentCollection
         */
        $em->persist($this->role);
        $em->flush();

        $groups = $this->role->getGroups();
        $groups->removeElement($group); // first remove element before adding a new one

        $group = new Group('Group Test 2');
        $em->persist($group);
        $em->flush();
        $groups->add($group);        

        $this->role->setGroups($groups);

        $this->assertEquals($groups, $this->role->getGroups());

WHAT WORKS:

        /**
         * Test ArrayCollection
         */
        $group = new Group('Group Test');
        $em->persist($group);
        $em->flush();

        $groups = new ArrayCollection();
        $groups->add($group);

        $this->role->setGroups($groups);

        $this->assertEquals($groups, $this->role->getGroups());

        /**
         * Test PersistentCollection
         */
        $em->persist($this->role);
        $em->flush();

        $groups = $this->role->getGroups();

        $group2 = new Group('Group Test 2');
        $em->persist($group2);
        $em->flush();
        $groups->add($group2);  // first adding a new element before removing one

        $groups->removeElement($group);

        $this->role->setGroups($groups);

        $this->assertEquals($groups, $this->role->getGroups());

Hope this helps in any way... I tried figuring it out on my own but I am too drunk right now xD

Comment by Benjamin Eberlei [ 10/Feb/12 ]

Thanks for the report, formatted it

Comment by Benjamin Eberlei [ 10/Feb/12 ]

Which version is that btw?

Comment by Steve Müller [ 16/Feb/12 ]

Occurs in version 2.1.6

Comment by Benjamin Eberlei [ 20/Feb/12 ]

If group is the owning side, why do you only set Role::$groups? This has to be the other way around or not?

Comment by Benjamin Eberlei [ 20/Feb/12 ]

@Steve

I cannot reproduce your issue.

Attached is a test script.

Your code is very weird btw, why are you getting and setting groups collection? It is passed by reference so you can just have something like $role->addGroup() and $role->removeGroup() and encapsulate the logic?

Also your tests are pretty useless, you check if two variables which are the same reference to the same collection are the same. Which should always be true.

@Lee

Can you provide more details? I cant verify this without more details.

Comment by Alexander [ 09/Feb/13 ]

Can anyone provide us with more feedback?





[DDC-1555] Reference. 8 Work. with obj. Making "see "Transitive Persistence"" as link Created: 22/Dec/11  Updated: 22/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: 2.1, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.1.5
Fix Version/s: None
Security Level: All

Type: Documentation Priority: Minor
Reporter: Yaroslav Kiliba Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

8. Working with Objects:
"... if the relationships from X to these other entities are mapped with cascade=PERSIST or cascade=ALL (see "Transitive Persistence")."
"... with cascade=REMOVE or cascade=ALL (see "Transitive Persistence")."
and so on.
Maybe it's reasonable to make "Transitive Persistence" as links to http://www.doctrine-project.org/docs/orm/2.1/en/reference/working-with-associations.html#transitive-persistence-cascade-operations






[DDC-1511] Suggestion on the docs for batch processing Created: 25/Nov/11  Updated: 25/Nov/11

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

Type: Documentation Priority: Minor
Reporter: Jamie Wong Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

br0wser



 Description   

I am refering to the examples on

http://www.doctrine-project.org/docs/orm/2.0/en/reference/batch-processing.html

Let's say you want to process a bulk of 25 objects and have a batchsize of 20.
With the code provided the last 5 would not be saved as far as I understand unless you do another flush after the for-loop.

This is probably very clear to any experienced Doctrine developer but maybe it is also confusing for beginners like me (some internet sources say, that flush is executed automatically at the end of the request, but obviously it is not). Maybe this could be mentioned somewhere?






[DDC-1494] Query results are overwritten by previous query. Created: 15/Nov/11  Updated: 09/Feb/13

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

Type: Bug Priority: Minor
Reporter: J Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.3 + MySQL 5.5


Attachments: File DDC1494Test.php    

 Description   

I am running a query that JOINs three tables, with a simple WHERE:

$q = $em->createQuery("

SELECT cat, n, c
FROM Project_Model_NoticeCategory cat
JOIN cat.notices n
JOIN n.chapters c
WHERE
c.id = :chapter_id

");

When I do this:

  $q->setParameter('chapter_id', 1);
  $a = $q->getResult();

  $q->setParameter('chapter_id', 2);
  $b = $q->getResult();

$b always has the wrong results. Running the following code:

  $q->setParameter('chapter_id', 1);
  $a = $q->getResult();

  $q->setParameter('chapter_id', 2);
  $b = $q->getResult();
  $z = $q->getArrayResult();

BUG Results: $b != $z (getArrayResult IS CORRECT, it refreshes the results) Note: $a==$b (which is wrong)

Explanation:

There is a chapter table, this has a many-to-many join to notices (these are meta info
about the chapter – a little like tagging a blog post) the notices are grouped into
categories.

Data model:

/**
 * @Entity
 * @Table(name="chapter")
 */
class Project_Model_Chapter
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
 
    /** @Column(type="string") */
    private $title;

	/**
	 * @ManyToMany(targetEntity="Project_Model_Notice", mappedBy="chapters")
	 */
	private $notices;
	
	.... /lots of code snipped/ ....
	
}


/**
 * @Entity
 * @Table(name="notice")
 */
class Project_Model_Notice
{
	/**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
 
    /** @Column(type="string") */
    private $title;
	
	/**
	 * @ManyToMany(targetEntity="Project_Model_Chapter", inversedBy="notices")
	 * @JoinTable(name="chapter_notice")
	 */
	private $chapters;
	
	/**
	 * @ManyToOne(targetEntity="Project_Model_NoticeCategory", inversedBy="notices")
	 */
	private $notice_category;
	
	.... /lots of code snipped/ ....
	
}

/**
 * @Entity
 * @Table(name="notice_category")
 */
class Project_Model_NoticeCategory
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
	/** @Column(type="string") */
    private $title;
	
	/**
	 * Bidirectional - One-To-Many (INVERSE SIDE)
	 *
	 * @OneToMany(targetEntity="Project_Model_Notice", mappedBy="notice_category", cascade={"persist", "remove"})
	 */
	private $notices;

	.... /lots of code snipped/ ....
	
}

Data fixtures:

$tools = new \Project_Model_NoticeCategory;
$tools->setTitle('Tools');
		
$spanner = new \Project_Model_Notice;
$spanner->setTitle('spanner');
$tools->addNotice($spanner);
		
$drill = new \Project_Model_Notice;
$drill->setTitle('power drill');
$tools->addNotice($drill);
		
$this->em->persist($tools);
$this->em->flush();

$tools = new \Project_Model_NoticeCategory;
$tools->setTitle('Safety');
		
$gloves = new \Project_Model_Notice;
$gloves->setTitle('gloves');
$tools->addNotice($gloves);
		
$goggles = new \Project_Model_Notice;
$goggles->setTitle('goggles');
$tools->addNotice($goggles);
		
$this->em->persist($tools);
$this->em->flush();

$chapter1 = new \Project_Model_Chapter;
$chapter1->setTitle('Chapter 1');
$this->em->persist($chapter1);

$chapter2 = new \Project_Model_Chapter;
$chapter2->setTitle('Chapter 2');
$this->em->persist($chapter2);

$chapter1->addNotice($spanner);
$chapter1->addNotice($gloves);

$chapter2->addNotice($spanner);
$chapter2->addNotice($gloves);
$chapter2->addNotice($drill);
$chapter2->addNotice($goggles);

// now persist and flush everything

Initial investigation:

I think it has something to do with HINT_REFRESH ? Stepping through:

ObjectHydrator->_hydrateRow
ObjectHydrator->_getEntity

when it requests the Project_Model_Category from the unit of work, it
seems that the second query is simply grabbing the cached results from
the first results. This MUST be wrong as the second query uses a
different query (the ID changes) and all the results are wrong.



 Comments   
Comment by Benjamin Eberlei [ 15/Nov/11 ]

Fixed formatting

Comment by Benjamin Eberlei [ 18/Nov/11 ]

are you using result caching?

Comment by J [ 21/Nov/11 ]

This is part of my bootstrap
,
,

		
$config = new \Doctrine\ORM\Configuration();
		
$cache = new \Doctrine\Common\Cache\ArrayCache;
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
		
// driver: schema
$driver = $config->newDefaultAnnotationDriver(
	APPLICATION_PATH . '/models'
);
$config->setMetadataDriverImpl($driver);

Comment by Benjamin Eberlei [ 15/Dec/11 ]

Cannot reproduce it with the script attached. Can you try to modify this to fail or write your own testcase?

Comment by Benjamin Eberlei [ 15/Dec/11 ]

Downgraded

Comment by Alexander [ 09/Feb/13 ]

Please provide extra feedback.





[DDC-1493] Improving in() from ExpressionBuilder Created: 15/Nov/11  Updated: 15/Nov/11

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

Type: Improvement Priority: Minor
Reporter: Andreas Hörnicke Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Instead of this piece of code:

$literal = $expr->literal($v);
$expr->andX(
  $expr->eq('at.key', $expr->literal($k)),
  $expr->orX(
    $expr->eq('a.valueInt', $literal),
    $expr->eq('a.valueText', $literal),
    $expr->eq('a.valueDate', $literal)
  )
);

I would like to simplify my query by using this syntax:

$expr->andX(
  $expr->eq('at.key', $expr->literal($k)),
  $expr->in($expr->literal($v), array('a.valueInt', 'a.valueText', 'a.valueDate'))
);





[DDC-1444] Be able to set a value also used in relation Created: 21/Oct/11  Updated: 21/Oct/11

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

Type: Improvement Priority: Minor
Reporter: Cedric Lahouste Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I am using a string field for data and for an optional relation too.
I am not using a ID because the second entity is from a third party application.

I used two variables in my entity mapping to the same field.

/**

  • @var string $an
    *
  • @ORM\Column(name="an", type="string", length=20, nullable=false)
    */
    private $an;

/**

  • @ORM\OneToOne(targetEntity="DataLinked")
  • @ORM\JoinColumn(name="an", referencedColumnName="part")
    */
    private $linked;

The getter is working fine.

The problem occurs when I create a new entity and would like to persist it.
As the field is used twice, the value of the second variable is erasing the first value.

At the line 525 of Doctrine\ORM\Persisters\BasicEntityPersister , I added the following test to update a null value only if there is no fieldName existing.

...
foreach ($assoc['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) {
if ($newVal === null) {
if(!isset($this->_class->fieldNames[$sourceColumn]) || in_array($sourceColumn, $this->_class->identifier))

{ $result[$owningTable][$sourceColumn] = null; }

} else if ($targetClass->containsForeignIdentifier) {
...

(!isset($this->_class->fieldNames[$sourceColumn]) : Test if there is no existing fieldName
in_array($sourceColumn, $this->_class->identifier)) : avoid skipping identifier definition because ID is listed in fieldNames!

What do you think about that?

Thanks.






[DDC-1423] Improving ReadOnly annotation by caching query results Created: 16/Oct/11  Updated: 16/Oct/11

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

Type: Improvement Priority: Minor
Reporter: Joseph Silvestre Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We should be able to tell Doctrine that we want the result of requests on ReadOnly marked Entities to be cached.

For instance:
$person->getMoodInformation();
$person->getCityInformation();

CityInformation are not likely to change so it would make sense to cache it and retrieve only MoodInformation (by using an annotation on the concerned Entity).

What would be even better is to tag which properies we want to hydrate from database and which properties we want to hydrate from cache.






[DDC-1413] Automatically create index for discriminator column Created: 11/Oct/11  Updated: 12/Jun/13

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

Type: Improvement Priority: Minor
Reporter: A.J. Brown Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

It would be nice if the command line orm schema-tool would suggest an index on the discriminator column for single inheritance tables. Since that column would almost always be in the query, I can't think of a case when you wouldn't want it to be in an index



 Comments   
Comment by Menno Holtkamp [ 12/Jun/13 ]

This topic suggests it is a bad practice though:
https://forum.hibernate.org/viewtopic.php?f=9&t=961578

In case of a big STI hierarchy, this might become usefull, additional testing required. However, as soons as a STI hierarchy becomes big, Class Table Inheritance might be more appropriate...





[DDC-1409] Download common 404 Created: 10/Oct/11  Updated: 10/Oct/11

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

Type: Documentation Priority: Minor
Reporter: Thomas Tourlourat - Armetiz Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

404 on Common download link : http://www.doctrine-project.org/projects/common/download






[DDC-1405] Define semantics of comparison operators, particularly with regard to null values Created: 06/Oct/11  Updated: 12/Oct/11

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

Type: Improvement Priority: Minor
Reporter: Daniel Alvarez Arribas Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The Doctrine 2 reference documentation defines the comparison operators syntactically, as:

ComparisonOperator  ::= "=" | "<" | "<=" | "<>" | ">" | ">=" | "!="

Now, without experimentation, it is pure guesswork to tell whether e. g. null = null, or e. g. null <> null, or null = 0, or null <> 0 are considered true statements in DQL.

In SQL semantics, all four statements would be false (or more precisely, null). In PHP semantics, both null == null and null == 0 would be true, while null != null and null != 0 would be false.

It would be helpful to have the semantics of the comparison operators defined. While comparisons with non-null values behave in a common-sense way, it is hard to guess how queries involving comparison operators on fields allowing null values or null query arguments will filter the results, without knowing the exact semantics of the comparison operators with regard to null values.

It would be great if this could be clarified in the docs.

Thanks.






[DDC-1373] Map file with specific class Created: 13/Sep/11  Updated: 14/Feb/12

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

Type: Improvement Priority: Minor
Reporter: Thomas Tourlourat - Armetiz Assignee: Fabio B. Silva
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Debian LAMP - PHP5.3 - Apache 2



 Description   

Hi there,
AbsractFileDriver is using the filename to know the managed class.

It's a cool feature because it's allow loading on-demand.
The problem is, that the filename must be the name of the Class.

It should be great to be able to manually map XML/YAML File description to a Class, like :
$drivers->addMappingFile ( array ( "filename" => "class", "filename2" => "class2") );

This feature is simple to implement, just add a new array inside AbsractFileDriver to know the mapping.
When using the current method with addPaths, parse the folder to get traditional XML/YAML file where filename corresponding to classname and add it to the mapping array.

AbsractFileDriver->getAllClassNames () just return value of mapping array.
The mapping array is store inside cache.

With this new feature, it allow developers to create a pretty folder that contains entities mapping.

Armetiz.



 Comments   
Comment by Guilherme Blanco [ 20/Dec/11 ]

Updating fix version





[DDC-1370] preInsert, postInsert, prePersist, postPersist, preUpdate, postUpdate code and documentation of events Created: 09/Sep/11  Updated: 26/Feb/14

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

Type: Improvement Priority: Minor
Reporter: Guilherme Blanco Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Currently we have a set of Lifecycle events, but they seem to be misleading both in actual implementation and documentation.

One good example is prePersist and postPersist, which is only fired when you're creating new entities. It should be renamed to preInsert and postInsert.
As of preUpdate and postUpdate, they seem quite valid.

But if we rename prePersist and postPersist to (pre|post)Insert, we may have a situation where you wanna cover both insert and update.
For this, (pre|post)Persist should be reinstated, but acting differently from what it does currently.



 Comments   
Comment by Rafael Dohms [ 09/Sep/11 ]

Also, documentation for post* methods is broken at the website:

"Changes in here are not relevant to the persistence in the database, but you can use this events to"

It cuts off in mid-sentence.

Comment by Guilherme Blanco [ 09/Dec/11 ]

RDohms, this paragraph was already sorted out.

The actual ticket is still valid here.

Comment by Guilherme Blanco [ 20/Dec/11 ]

Updating fix version

Comment by Matt McNeill [ 26/Feb/14 ]

Commenting here to say that this caused a lot of headaches for our project until we got it sorted out what these events really do.

The problem is that the term 'persist' is ambiguous - it means both persist and update in the context of the persist() function call, but only means INSERT in the context of the event system.





[DDC-1332] Specify Custom ProxyFactory Created: 15/Aug/11  Updated: 18/Feb/14

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

Type: New Feature Priority: Minor
Reporter: Eric Clemmons Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

My tweet:

> @beberlei Have you heard of overriding the ProxyFactory to allow caching of lazy-loaded entities? Trying to do that now

The majority of our data is quite stagnant and so I was shoehorning the capability of the generated proxies to use a custom class.

My new proxy, in short, will lazy-load the data as normal the first time around, but also stores it in Memcache using an injected adapter. Upon subsequent lazy-loading, memcache is used rather than a call to the DB.

I can't decide if this is better suited for the EntityPersister (which has already been discussed at length), but it seems to fits nicely with a custom proxy.



 Comments   
Comment by Benjamin Eberlei [ 15/Aug/11 ]

This is the wrong extension point to override the proxy factory. It should be in the persisters.

Comment by Eric Clemmons [ 15/Aug/11 ]

Ah, so my doubts were well founded.

The branch allowing custom EntityPersisters has not been merged in yet, has it? Or, a better question, will it be? That will dicate if I need to maintain a separate fork for this functionality or find other means to handle this.

I know how hesitant we were for adding any extension point, because then we feel we have to support it, which makes me wonder if "LifeCycleCallback::preFetch" or similar is a potential alternative.

Comment by Christian Schmidt [ 18/Feb/14 ]

Related: https://github.com/doctrine/doctrine2/pull/243





[DDC-1329] Documentation for @JoinColumn may be incorrect Created: 13/Aug/11  Updated: 13/Aug/11

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

Type: Documentation Priority: Minor
Reporter: Damon Jones Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The Documentation for @JoinColumn annotation states:
"This annotation is not required. If its not specified the attributes name and referencedColumnName are inferred from the table and primary key names."

However, this seems not to be correct. If you have non-standard name for the @Id columns for a @OneToMany/@ManyToMany the name and referencedColumnName are not correctly inferred.

https://gist.github.com/e61bf8f4462870ffd4f3






[DDC-1283] Possible issue with PersistentCollection#getDelete/InsertDiff() Created: 21/Jul/11  Updated: 07/Sep/13

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

Type: Improvement Priority: Minor
Reporter: Glen Ainscow Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Using the following code, when you go from (1, 2) to (1), (2) is deleted as expected. However, if you go from (1, 2) to (2), (1) and (2) are deleted and (2) is then inserted. Is this the desired behaviour? (i.e. 2 extra queries)

$bracket->getTournamentLocations()->takeSnapshot();

$col = $bracket->getTournamentLocations()->unwrap();

$col->clear();

foreach ($form->getValue('tournamentLocations') as $id) {
    $col->add($em->getReference('Tournaments_Model_TournamentLocation', $id));
}

$bracket->getTournamentLocations()->setDirty(true);


 Comments   
Comment by Benjamin Eberlei [ 26/Jul/11 ]

First, you are using internal API therefore you are on your own anyways.

This is marked as improvment now, the functionality works, it may just be inefficient.

Comment by Guilherme Blanco [ 09/Dec/11 ]

Hi,

I'm marking issue as invalid because you're conceptually wrong.
What you're trying to do is telling that a collection of new entities is holded by a collection of Persistent entities.
The reference internally of PersistentCollection to ArrayCollection means a lot here.

Correct code would be you to regenerate the collection (a new ArrayCollection) and just assign it to setTournamentLocations($newCollection);

Does this explanation is enough for you?

Cheers,

Comment by Glen Ainscow [ 23/Dec/11 ]

Hi Guilherme,

If I do this:

$locations = new ArrayCollection();

foreach ($form->getValue('tournamentLocations') as $id) {
    $locations->add($em->getReference('Tournaments_Model_TournamentLocation', $id));
}

$bracket->setTournamentLocations($locations);

... then all the records are deleted, before adding the new records. This is inefficient and causes extra, unnecessary write operations.

Can't Doctrine perform diffs when persisting the collection, so that only the necessary deletes and inserts are executed?

Comment by Guilherme Blanco [ 13/Jan/12 ]

We could add it, but I don't think it worth the effort.
Main problem with this one is that we use C-level binary comparison to get the diff. That's what you entities/hash pointers are different.
We would have to write our own diff-comparator for both collections, which would probably slowdown the entire Doctrine.

I'd rather consider that it's not possible to be done at the moment, but I need much more investigation for that. This will be something that I'll probably only do when I look at this issue again with a lot of time (which is really hard to happen).

If you have some spare time, feel free to make some attempts.
Just don't forget to enable performance tests in Doctrine Unit Test suite.





[DDC-1248] Documentation regarding prePersist and postPersist events a bit lacking Created: 04/Jul/11  Updated: 04/Jul/11

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

Type: Documentation Priority: Minor
Reporter: Helmer Aaviksoo Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Browser



 Description   

Please make it more clear that prePersist and postPersist events are called only when creating new entity (that is, prior and after a database insert).

IRC log:
helmer
Hi. I have a question regarding (pre|post)persist events. Why are the events ignored for second persist (should fire prePersist) + flush (should fire postPersist) in the following pastie: http://pastebin.com/V8CrPWkM Is it a bug or am I missing sth?
Stof
helmer: there is no second persist. persist() means saying Doctrine to manage the entity. Once it is managed, you are not persisting it anymore but updating it
helmer
Stof: so basically one could define these two events for themselves as (pre|post)Insert?
beberlei
yes
helmer
thanks beberlei&stof! though a suggestion to docteam .. perhaps make it more clear to people like me, current doc can be kind of misleading ie: "There are two ways for the prePersist event to be triggered. One is obviously when you call EntityManager#persist()" http://www.doctrine-project.org/docs/orm/2.0/en/reference/events.html#prepersist

Pastie code (probably expired by now):
$entity = new Entity();

$entity->setSomething('xxx');
$this->em->persist($entity);
$this->em->flush();

$entity->setSomething('yyy');
$this->em->persist($entity);
$this->em->flush();






[DDC-1206] Add option to SchemaTool for ignoring unsupported tables Created: 13/Jun/11  Updated: 05/Mar/12

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

Type: New Feature Priority: Minor
Reporter: Jani Hartikainen Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

I suggest adding a new feature to SchemaTool, which allows you to ignore tables, which contain unsupported column types.

Use case:

  • You have a legacy database, or a database that is also shared with another application
  • You want to use SchemaTool to speed up development
  • The database contains tables which are not used in the Doctrine 2 application, and contain unsupported column types

I've encountered this already a few times myself - Basically if you try to use orm:schema-tool:update with a database that contains tables with unsupported column types, it'll throw an error and you won't be able to use it at all. Because schema tool is extermely convenient when developing, I think it would be very useful to have support for this feature.

Implementation:

I think this should be doable by just changing SchemaTool/SchemaManager so, that SchemaManager would contain an additional method (or flag) which works like createSchema, but ignores tables that cause an exception, and SchemaTool would include a flag for using this instead of the standard approach.

I'm looking into implementing this myself, and will submit a patch if this seems like a reasonable approach.



 Comments   
Comment by Jani Hartikainen [ 15/Jun/11 ]

Relevant patches (pull request made):

DBAL https://github.com/jhartikainen/dbal/tree/DDC-1206
ORM https://github.com/jhartikainen/doctrine2/tree/DDC-1206

Comment by Michael Graf [ 05/Mar/12 ]

has there been any progres on this feature? I have POINT in my DB and would rather ignore the table than create a custom type.





[DDC-1198] Add PHPDocs to annotationclasses Created: 08/Jun/11  Updated: 08/Jun/11

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

Type: Documentation Priority: Minor
Reporter: Robert Gruendler Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

If an IDE would like to support annotations, it's currently only possible to display all resolvable classes in a code-hint menu when autocompleting annotations, as
basically any class can be used for annotations.

To make it possible for IDEs to detect classes which are explicitly meant to be used as annotations, it would be nice to agree on some common
way of documenting annotations in PHPDocBlocks.

Here's an example of what this could look like:

https://github.com/pulse00/doctrine2/commit/25a14e9edc406edfd33e54fc38922a191e9cbe83

This way IDEs can prioritize annotated classes in code-hints and add additional information to the user.






[DDC-1123] Confusing error message when an ID is missing Created: 25/Apr/11  Updated: 15/Nov/11

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

Type: Improvement Priority: Minor
Reporter: Jani Hartikainen Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The error message you get when an entity is missing an ID when attempting to persist it is rather confusing.

"Entity of type Some\Entity\Name is missing an assigned ID."

This does not tell me anything at all. I had absolutely no idea what an assigned ID was. I totally randomly noticed that I had mistyped @GeneratedValue as @GenratedValue, and fixing it fixed the issue.

Perhaps the message makes sense if you're familiar with Doctrine 2 internals, but I think it should be changed to something more helpful, such as "Entity of type X is missing primary key".

Alternatively it could keep the same message, but it could suggest a possible error ("Does the entity have a primary key set?") or perhaps the documentation could include a reference to it to help debug.



 Comments   
Comment by Liju P M [ 15/Nov/11 ]

I too came across the same issue. The error message is not up to the mark here. In my case, mapping for primary key was missing the generator strategy,

<generator strategy="IDENTITY"/>

Thanks Jani Hartikainen for the hint.





[DDC-1103] Addding an event before the load of collections Created: 05/Apr/11  Updated: 05/Apr/11

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

Type: New Feature Priority: Minor
Reporter: Christophe Coevoet Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None


 Description   

An event triggered when loading collections would be useful for performances. The use case would be batch querying some stuff instead of doing a query per object of the collection in a postLoad event.
For instance, the Translatable extension from https://github.com/l3pp4rd/DoctrineExtensions loads the translations on postLoad which result in many queries. Being able to load them all in a single query would be useful.



 Comments   
Comment by Gediminas Morkevicius [ 05/Apr/11 ]

I think custom persisters will solve these issues, lets wait for them, there are already enough events





[DDC-1081] Unnecessary JOIN when selecting ManyToMany/Join Table by ID. Created: 27/Mar/11  Updated: 28/Mar/11

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

Type: Improvement Priority: Minor
Reporter: David Reisch Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

With the schema:

 
Image
    @Id
    $id

Tag
    @Id
    $Id

Tag_Image
    @Id
    @OneToOne(targetEntity="Tag")
    @JoinColumn(name="tag")
    $tag

    @Id
    @OneToOne(targetEntity="Image")
    @JoinColumn(name="image")
    $image

Given the following DQL,

    SELECT img
    FROM Image 
    LEFT JOIN img.tags tag
    WHERE tag.id=:tag

Doctrine Generates this SQL

 
    SELECT i0_.id AS id1 
    FROM Image i0_ 
    LEFT JOIN Tag_Image t2_ 
        ON i0_.id = t2_.image 
    LEFT JOIN Tag t1_ 
        ON t1_.id = t2_.tag 
    WHERE t1_.id = 37

Which unncessarily joins against Tag, given that the foreign key Tag.id is also found in Tag_Image.tag.



 Comments   
Comment by Benjamin Eberlei [ 27/Mar/11 ]

This is not a bug, but expected behavior.

You can select against the alias if its on the owning side of the association:

SELECT img
FROM Image img 
WHERE img.tag=:tag

In this case it is not a left join though, if you want a left join you HAVE to join.

Comment by David Reisch [ 27/Mar/11 ]

There is no owning isde of the association, you can clearly see there is an association table/entity.

I can't understand how this behavior is expected. If no properties of Tag are selected for, there is no need to join against Tag since the id is already available via the association table.

Comment by Benjamin Eberlei [ 28/Mar/11 ]

I misread the mappings, sorry, i though its a @OneToOne but its actually an assocition entity with @OneToOnes.

Can you show me the Image::$tags mapping also?

Comment by David Reisch [ 28/Mar/11 ]

That is correct, thanks for taking another look at this.
Sorry I had forgotten to include that information.

Image
    /**
        @Id
    */
    $id

    /**
        @ManyToMany(targetEntity="Tag")
        @JoinTable(name="Tag_Image", 
                            joinColumns={@JoinColumn(name="image")},
                            inverseJoinColumns={@JoinColumn(name="tag")})
    */
    $tags
Comment by Benjamin Eberlei [ 28/Mar/11 ]

The targetEntity is wrong. I suppose it should be Image_Tag or not? If it should be Tag, then you don't need that Image_Tag entity at all.

In that case i have to check if you can use the shortcut notation, however it will again not work with the left join - only inner. This is an assumption the ORM makes and there is not yet code included for the optimization. This is not a bug, but an improvement ticket. The functionality works.

Comment by David Reisch [ 28/Mar/11 ]

No argument on the ticket type...

Ahh, I store some metadata in Tag_Image, which is why I manage it explicitly.

In any case thanks for looking at this.

Comment by Benjamin Eberlei [ 28/Mar/11 ]

If you change the targetEntity to Tag_Image then it might already be enough to get this working without another join.

Comment by David Reisch [ 28/Mar/11 ]

With this change, the original query is invalid:

    LEFT JOIN i.tags t
    WHERE t.id=:tag

Because i.tags of type Tag_Image has no field id

[Semantical Error] line 0, col 138 near 'id=:tag ': Error: Class domain\Tag_Image has no field or association named id

I attempt the logical modification:

    LEFT JOIN i.tags t
    WHERE t.tag=:tag

and get

SELECT i0_.id AS id0
FROM Image i0_ 
LEFT JOIN Tag_Image t1_ ON i0_.id = t1_.image 
LEFT JOIN Tag_Image t1_ ON t1_.id = t1_.tag 
WHERE t1_.tag = 37

SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 't1_





[DDC-1058] Documentation on orphan removal in XML Mapping is incorrect Created: 04/Mar/11  Updated: 04/Mar/11

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

Type: Documentation Priority: Minor
Reporter: Josh Freed Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The XML Mapping documentation indicates that "orphan-removal" is an attribute on One-to-One or Many-to-One elements, but in DoctrineORM version 2.0 that does not work. It seems I have to make "orphan-removal" a child attribute of those elements to turn it on.

Just to be clear:

Documentation says to do this, but it does not work:
<one-to-many field="..." orphan-removal="true"> ... </one-to-many>

This does work:
<one-to-many field="..."> <orphan-removal>true</orphan-removal> </one-to-many>






[DDC-1015] @DiscriminatorColumn is not required anymore Created: 03/Feb/11  Updated: 03/Feb/11

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

Type: Documentation Priority: Minor
Reporter: Karsten Dambekalns Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Since DDC-514 there is a default in place for this, thus the description is wrong in stating this is required.






[DDC-987] How to register lifecycle callbacks from YAML is not done correctly in the Events section of the documentation. Created: 14/Jan/11  Updated: 27/Nov/13

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

Type: Documentation Priority: Minor
Reporter: Amir Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

http://www.doctrine-project.org/docs/orm/2.0/en/reference/events.html

The above URL has an example of how to register lifecycle callbacks from YAML, but actually it does not work. The correct way of doing it is mentioned on the page: http://www.doctrine-project.org/docs/orm/2.0/en/reference/yaml-mapping.html



 Comments   
Comment by Jeremy Postlethwaite [ 27/Nov/13 ]

Please close this issue

Both pages now have the same documentation.

Doctrine example
  lifecycleCallbacks:
    prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
    postPersist: [ doStuffOnPostPersist ]
Partial stack trace exhibiting call:
/redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php(73) : eval()'d code :: Tue, 26 Nov 2013 22:05:03 -0800 $eventName

prePersist

/redacted-path/src/Application/Modules/System/Entity/Sites.php(161) : eval()'d code :: Tue, 26 Nov 2013 22:05:03 -0800 $args

object(Doctrine\ORM\Event\LifecycleEventArgs)[839]
  private 'objectManager' (Doctrine\Common\Persistence\Event\LifecycleEventArgs) => 
    object(Doctrine\ORM\EntityManager)[330]
      private 'config' => 
        object(Doctrine\ORM\Configuration)[156]

/redacted-path/src/Application/Base.php(371) : eval()'d code :: Tue, 26 Nov 2013 22:05:03 -0800

#0 /redacted-path/src/Application/Modules/System/Entity/Sites.php(161): Application\Base::puke(Object(Doctrine\ORM\Event\LifecycleEventArgs), '/www/sites/loca...', true)
#1 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php(104): Application\Modules\System\Entity\Sites->prePersist(Object(Doctrine\ORM\Event\LifecycleEventArgs))
#2 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(845): Doctrine\ORM\Event\ListenersInvoker->invoke(Object(Doctrine\ORM\Mapping\ClassMetadata), 'prePersist', Object(Application\Modules\System\Entity\Sites), Object(Doctrine\ORM\Event\LifecycleEventArgs), 2)
#3 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(1621): Doctrine\ORM\UnitOfWork->persistNew(Object(Doctrine\ORM\Mapping\ClassMetadata), Object(Application\Modules\System\Entity\Sites))
#4 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(1577): Doctrine\ORM\UnitOfWork->doPersist(Object(Application\Modules\System\Entity\Sites), Array)
#5 /redacted-path/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(624): Doctrine\ORM\UnitOfWork->persist(Object(Application\Modules\System\Entity\Sites))
#6 /redacted-path/src/Application/Modules/Application/Controller/AbstractEntityFormActionController.php(128): Doctrine\ORM\EntityManager->persist(Object(Application\Modules\System\Entity\Sites))

My configuration was slightly different from the example.

  • Changed some of the details to protect the innocent.
My configuration inherited from a mappedSuperclass
  lifecycleCallbacks:
    prePersist: [ prePersist ]
    preFlush: [ preFlush ]




[DDC-986] bad cli commands in ORM introduction Created: 14/Jan/11  Updated: 15/Jan/11

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

Type: Documentation Priority: Minor
Reporter: Stepan Tanasiychuk Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I read mini tutorial http://www.doctrine-project.org/docs/orm/2.0/en/reference/introduction.html#mini-tutorial and try run command "doctrine orm:schema-tool --drop"

TIP When you create new model classes or alter existing ones you can recreate the database schema with the command doctrine orm:schema-tool --drop followed by doctrine orm:schema-tool --create.

It's not worked for me:

[InvalidArgumentException]
Command "orm:schema-tool" is not defined.

But command "doctrine orm:schema-tool:drop --force" and "doctrine orm:schema-tool:create" is worked.
It's bug in documentation?






[DDC-977] Allow for multiple filters to be set from the command line Created: 11/Jan/11  Updated: 11/Jan/11

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

Type: Improvement Priority: Minor
Reporter: Stephen Lang Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

OSX, PHP 5.3, MySQL 5.1



 Description   

I'm working with an existing database with a large number of tables, I would like to generate metadata mappings for a subset of tables using the command below. The Doctrine code states that the 'filter' option should be an array but there doesn't seem to be any way to pass in an array from the command line? Is the command below the syntax intended for the filter option? If so this may be a Symfony issue?

Command
php doctrine.php orm:convert-mapping --filter="TableOne" --filter="TableTwo" --from-database xml /Path/To/Metadata

Expected result
Processing entity "TableOne"
Processing entity "TableTwo"
Exporting "xml" mapping information to "/Path/To/Metadata"

Actual result
Processing entity "TableTwo"
Exporting "xml" mapping information to "/Path/To/Metadata"

Relevant code
http://j.mp/eJD963 (Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php)
http://j.mp/f1ADXm (Symfony/Component/Console/Input/ArgvInput.php)



 Comments   
Comment by Stephen Lang [ 11/Jan/11 ]

Changed priority to minor.





[DDC-957] When there is no GeneratedValue strategy on a primary key, setter function should be generated Created: 29/Dec/10  Updated: 29/Dec/10

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

Type: Improvement Priority: Minor
Reporter: Flyn San Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.3.3



 Description   

In the YAML/XML, if no GeneratedValue strategy is given for the primary key, a setter function is required in the generated entity class. Currently only a getter is made.






[DDC-935] copy function needs implementation Created: 15/Dec/10  Updated: 02/Jan/11

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

Type: Task Priority: Minor
Reporter: Jack van Galen Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The (deep)copy function of the entity manager is not yet implemented. I assume this is known, but I could not find any open issue on it. This is a pretty powerfull feature once implemented. The function body is completely empty however. Perhaps the tried code could be added so I and others could try and resolve the known issue with this function (recursion limit reached).



 Comments   
Comment by Benjamin Eberlei [ 15/Dec/10 ]

There was never code written for that function. I don't think its too problematic that this is missing. You only have to implement __clone (and do so safely as the docs/cookbook describes) and then pass this structure to persist. Optionally making use of cascade persist.

Comment by Marcus Stöhr [ 01/Jan/11 ]

I recently came accross this. Is there any best practice if you have to clone an entity who has several associations? I thought of grabbing them and clone them one by one. Or is there a more convenient way?

Comment by Benjamin Eberlei [ 02/Jan/11 ]

no, except implementing __clone and doing it there.





[DDC-900] Insufficient Error Information for orm:validate-schema Created: 29/Nov/10  Updated: 29/Nov/10

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

Type: Improvement Priority: Minor
Reporter: aurorius Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 2
Labels: None
Environment:

linux, php 5.3.3



 Description   

Running "doctrine orm:validate-schema" would return -> [Database] FAIL - The database schema is not in sync with the current mapping file.

It should have at least return the name of the table/field that is not in sync.






[DDC-891] DDC-117: No sequence generation with composite foreign key Created: 25/Nov/10  Updated: 25/Nov/10

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

Type: New Feature Priority: Minor
Reporter: Timo A. Hummel Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Given the following entity definitions, Doctrine does not attempt to manage generated values. For example, in MySQL, it is perfectly possible to create a composite primary key and set auto_increment on one of these. See below the code for issues that occur.

User.php
/**
 * @Entity
 */
class User {
	/**
	 * @Id
	 * @Column(type="integer")
	 * @GeneratedValue(strategy="AUTO")
	 */
	private $id;
	
	/**
	 * @Column(type="string")
	 */
	private $name;
	
	/**
	 * @OneToMany(targetEntity="PhoneNumber",mappedBy="id",cascade={"all"})
	 */
	private $phoneNumbers;
	
	public function setName ($name) {
		$this->name = $name;
	}
}
PhoneNumber.php
/**
 * @Entity
 */
class PhoneNumber {
	/**
	 * @Id
	 * @Column(type="integer")
	 * @GeneratedValue(strategy="AUTO")
	 */
	private $id;
	
	/**
	 * @Id
	 * @ManyToOne(targetEntity="User",cascade={"all"})
	 */
	private $user;
	
	/**
	 * @Column(type="string")
	 */
	private $phonenumber;
	
	public function setUser (User $user) {
		$this->user = $user;
	}
	
	public function setPhoneNumber ($phoneNumber) {
		$this->phonenumber = $phoneNumber;
	}
}
Invokation
$albert = new User;
$albert->setName("albert");
$em->persist($albert);

$phoneAlbert1 = new PhoneNumber();
$phoneAlbert1->setUser($albert);
$phoneAlbert1->setPhoneNumber("albert home: 012345");
$em->persist($phoneAlbert1);

The first issue which occurs is that Doctrine does not generate the field "id" within PhoneNumber set to auto_increment.

The second issue which occurs is that Doctrine becomes confused when inserting a new record into PhoneNumber, because of the following INSERT INTO statement:

Insert Statement
INSERT INTO PhoneNumber (user_id, phonenumber) VALUES (?, ?)
array(1) {
  [1]=>
  string(19) "albert home: 012345"
}

SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens


 Comments   
Comment by Roman S. Borschel [ 25/Nov/10 ]

I don't think this will ever be possible.

Comment by Timo A. Hummel [ 25/Nov/10 ]

Is there a technical reason for that? I mean, with DDC-117 we are aiming for composite foreign keys, or is DDC-117 cancelled?

Comment by Benjamin Eberlei [ 25/Nov/10 ]

A composite key is ALWAYS of the type "ASSIGNED" and cannot be a combination of different id generation strategies.

You could however write a prePersist Listener that does this for you.

Comment by Timo A. Hummel [ 25/Nov/10 ]

Okay, maybe this is a feature for 3.0 or so. However, I'd suggest leaving this bug open as this is something which needs to be documented once DDC-117 becomes integrated within the main branch.

Additionally, Doctrine should complain about different ID generation strategies. Right now it silently ignores it.





[DDC-878] Don't explicitly require object members (fields) to be defined in the entity class Created: 16/Nov/10  Updated: 16/Nov/10

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

Type: Improvement Priority: Minor
Reporter: Nick Daugherty Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently, Doctrine REQUIRES that a given entity class have protected or private members explicitly defined in the class (even if meta data mapping is handled elsewhere, such as in YAML). This is less than optimal...for example, many class implementations prefer to store all data in a protected $fields member, as an array, accessing the members with getters and setters.

Doctrine makes this behavior impossible. An exception is thrown if a field defined in meta data is not an explicit member of the class. Instead, it should 'take the meta data's word for it' that the field exists, and is accessible via getters and setters, without explicitly checking for the member. The meta data is already the authoritative source, I don't see why the double check should (or needs to) be performed (although I am not familiar with Doctrine internals). Since Doctrine recommends making members private, I have to assume it is already hydrating them with the get/set accessors anyway...so it should just rely on them.

Quick example use case (notice 'name' is not actually a member...it is stored in $fields and assume meta data is defined in a separate yaml file):

class User

{ protected $fields = array(); public function getName() { return $this->fields['name']; } public function setName($name) { $this->fields['name'] = $name; } }

 Comments   
Comment by Benjamin Eberlei [ 16/Nov/10 ]

This maybe a potential optimization for a very future version. However currently we heavily rely on the Reflection support for properties, which kind of makes a change of this a very complex undertaking.





[DDC-838] SchemaTool - ignores the attribute uniq in relations Created: 13/Oct/10  Updated: 29/Oct/10

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

Type: Improvement Priority: Minor
Reporter: gektor Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Ubuntu, PHP 5.3.2, MySQL



 Description   
Mapper
<entity name="Default_Model_Test" table="test">
  <id name="id" type="integer" column="id">
    <generator strategy="AUTO"/>
  </id>
  <field name="blabla" column="blabla" type="boolean"/>
  <one-to-one field="user" target-entity="Users_Model_User">
    <join-column name="users_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE" unique="false" />
  </one-to-one>
</entity>
SQL
CREATE TABLE test (id INT AUTO_INCREMENT NOT NULL, users_id INT DEFAULT NULL, blabla TINYINT(1) NOT NULL, UNIQUE INDEX test_users_id_uniq (users_id), PRIMARY KEY(id)) ENGINE = InnoDB;
ALTER TABLE test ADD FOREIGN KEY (users_id) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE;

Actual:
UNIQUE INDEX test_users_id_uniq (users_id)

Expected:
INDEX test_users_id (users_id)



 Comments   
Comment by Benjamin Eberlei [ 14/Oct/10 ]

Verified, i just don't understand why you are using a one-to-one relation and then "deactivate" the database constraint for this. You could easily use Many-To-One

Comment by gektor [ 14/Oct/10 ]

You are right. It's not a bug, it's feature.

Comment by Benjamin Eberlei [ 29/Oct/10 ]

This might still be a good improvement to allow the flexibility, but its not a bug. Updating to "Minor Improvmenet for 2.x"





[DDC-747] Add support for table, column and indexes comments Created: 13/Aug/10  Updated: 14/Aug/10

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: Minor
Reporter: s9e Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 5
Labels: None


 Description   

It would be nice to add support for table comments, column comments and indexes comments, i.e.

@Table(
    name="ecommerce_products",
    comment="Contains products",
    indexes={@index(name="search_idx", comment="Makes finding people by name easier", columns={"name", "email"})}
)

@Column(type="integer", comment="Stores the user's age, in years")

MySQL supports comments via ALTER TABLE since 4.1.
PostgreSQL support comments via COMMENT at least since 7.4.
SQLite doesn't appear to support table, column or indexes comments as of 3.7.
Oracle supports comments on tables and columns via COMMENT at least since 10.1. It doesn't appear to support comments on indexes.

For databases that don't support those persistent comments, you could use normal SQL comments in the table definition. Of course they wouldn't be stored by the database, but at least they would appear in the generated schema, that's better than nothing.






[DDC-740] Mantain a list of DQL reserved keywords Created: 09/Aug/10  Updated: 05/Sep/14

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

Type: Improvement Priority: Minor
Reporter: Guilherme Blanco Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 1
Labels: None


 Description   

We should keep a list of DQ reserved keywords, so users can check out what they can use or not.



 Comments   
Comment by Manasi [ 07/Aug/13 ]

Here is the list of reserved keywords for MySQL: http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html
The documentation does not clearly mention that the backticks for a column with a reserved keyword in the ORM mapping file. This file could be in xml, yaml or php.
So,the right way to apply backticks is: <field name="group" type="string" column="`group`" length="32" nullable="false"/>

Comment by Luiz Oliveira [ 05/Sep/14 ]

Here is the list of reserved keywords for PostgreSQL

http://www.postgresql.org/docs/7.3/static/sql-keywords-appendix.html





[DDC-718] Bottleneck in computeAssociationChanges()? Created: 24/Jul/10  Updated: 24/Jul/10

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

Type: Improvement Priority: Minor
Reporter: Benjamin Eberlei Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Reference
relates to DDC-600 Persisting Entities with unmanaged re... Closed

 Description   

It seems that since DDC-600 computeAssociationChanges() iterate over entries of an collections, even if they are not marked as cascadePersist. For large, hydrated collections this could potentially become a bottleneck.

Wouldn't it be better to save the "addedEntities" in an additional map inside "PersistentCollection" and retrieve those instead of calling $value->unwrap() ?



 Comments   
Comment by Roman S. Borschel [ 24/Jul/10 ]

Do you have any numbers to back this up? With large, hydrated collections the bottlenecks are likely elsewhere (SQL query, hydration)

Further, maintaining "addedEntities" is not as trivial as you might think. The current approach does not care about what happens in-between, it just computes a diff between the old and new state of the collection at commit time. Tracking added/removed objects as they come in and go is more cumbersome.

Comment by Benjamin Eberlei [ 24/Jul/10 ]

no numbers, i was just confused about the code, because i remembered it differently





[DDC-712] allow RIGHT JOIN or specifying the root class of the hydratation tree Created: 21/Jul/10  Updated: 22/Jul/10

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

Type: Improvement Priority: Minor
Reporter: Mihai Ilinca Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi! Let me start by saying you guys did a great job with Doctrine 1 and that I can't wait to start using Doctrine2

I will explain this feature request with an example. I have a User entity wich relates one to many to a Picture entity. Picture has a " is main picture" boolean field. Not all users have a main picture. I would like to be able to select all Users, each with their main picutre, if that exists, or some Null value, if it does not exists, in one query, using join. I would also like for the result collection to contain Picture entities on the first level, with the User beinng accessible as an aggregate of Picture.

The way I can think doing this is by using a RIGHT or LEFT join (not INNER) as to also select Users that don't have a main picture. I can do this by selecting

SELECT Picture p, p.User u FROM p RIGHT JOIN u WITH p.main=1

but right joins afik are not available atm in either version of Doctrine, or by selecting

SELECT User u, u.Picture p FROM u LEFT JOIN p WITH p.main=1

and somehow instructing the hydrator to consider Picture as the root object for the generated object tree and User as a "child" of Picture.

For users without a picture, the Picture object would somehow indicate it is NULL, while still holding a refference to the User.

Makes sense? If there is an alternate way to achieve this, please enlighten me, tough I think it would still add felxibility if we could hint the hydrator for the root object in a tree.



 Comments   
Comment by Benjamin Eberlei [ 22/Jul/10 ]

Why don't you model that as ManyToOne for the Main Picture and OneToMany for all pictures? Makes much more sense from an ORM perspsective, you would have your own property "User::$mainPicture"

Comment by Mihai Ilinca [ 22/Jul/10 ]

Thanks for the suggestion. However, this was just an example to demonstrate some lack of flexibility, I am not strictly looking for a solution to this example, but to the concept behind it.

Also, how would I get the result with Picture on the top level and User aggregated to Picture with the model you suggested? Unless I am missing something, wouldn't I end up in the same situation?

I can post-process the results myself and create a new collection easily, ofc, but it would be better (and more optimal) if I could tell the hydrator to do this, similar to how INDEXBY is passed as an option to the hydrator.





Add the notion of read-only entities (DDC-209)

[DDC-691] doctrine.readOnly query hint Created: 15/Jul/10  Updated: 31/May/12

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

Type: Sub-task Priority: Minor
Reporter: Roman S. Borschel Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 6
Labels: None


 Description   

Setting such a query hint to TRUE should result in all entities being retrieved by that query to be read-only for the purposes of change-tracking. Note that the entities themselves need not necessarily be read-only in general.

This feature is a flush performance tweak that can be used to query for objects but not let the returned objects run through change-tracking on flush. Any other managed objects are tracked as usual so you can do a read-only query for 100 entities and persist a new entity in the same unit of work with optimal flushing performance.



 Comments   
Comment by Konstantin [ 26/Dec/11 ]

Any news?
Why query hint? What about temporary switching like fetch mode changing via query object?

Comment by Gigi Largeanus [ 31/May/12 ]

Any news on this?

I think this is a must have feature. Thanks for all your work.





[DDC-677] Allow DQL DELETE statements to work with join table fk constraints Created: 10/Jul/10  Updated: 10/Jul/10

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

Type: New Feature Priority: Minor
Reporter: Benjamin Eberlei Assignee: