[DDC-886] Mapped Supperclass composite identifier is ignored in child class Created: 21/Nov/10  Updated: 16/Aug/14  Resolved: 27/Nov/10

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

Type: Bug Priority: Major
Reporter: Gediminas Morkevicius Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

all



 Description   

Currently $class->isIdentifierComposite value stays "false" if no new identifiers were added on child class..

patch proposal:
around line 270, file: ClassMetadataFactory.php

add line:
$class->isIdentifierComposite = $parent->isIdentifierComposite;

this way if supperclass had composite identifier and child had none identifiers
the result would be as suspected.



 Comments   
Comment by Benjamin Eberlei [ 27/Nov/10 ]

Schedule for RC1

Comment by Benjamin Eberlei [ 27/Nov/10 ]

Fixed





[DDC-727] Proxy instances should be able to get their correspondent ClassMetadata Created: 30/Jul/10  Updated: 19/May/14  Resolved: 15/Sep/10

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

Type: Bug Priority: Minor
Reporter: Guilherme Blanco Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None


 Description   

This should be possible:

$entity = $em->getReference('Foo' , 1); 
$class = $em->getClassMetadata(get_class($entity)); // ClassMetadata if Foo entity

Currently it seems to throw an Exception.



 Comments   
Comment by Benjamin Eberlei [ 15/Sep/10 ]

I added a testcase for this, it works.

http://github.com/doctrine/doctrine2/commit/d3419780f9daa3eaf0400c2b6fcee0234240b1de

Comment by Benjamin Eberlei [ 31/Mar/12 ]

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

Comment by Benjamin Eberlei [ 01/Apr/12 ]

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

Comment by Benjamin Eberlei [ 01/Apr/12 ]

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

Comment by Benjamin Eberlei [ 04/Apr/12 ]

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

Comment by Benjamin Eberlei [ 06/Apr/12 ]

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

Comment by Benjamin Eberlei [ 07/Apr/12 ]

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

Comment by Doctrine Bot [ 19/May/14 ]

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





[DDC-841] Generated SQL contains non-existen alias Created: 16/Oct/10  Updated: 02/Feb/11  Resolved: 31/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: John Kleijn Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Reference
relates to DDC-671 Table aliases wrongly computed with Y... Resolved
relates to DDC-826 Problem with @MappedSuperclass and as... Resolved
relates to DDC-1013 Possible issue with multiple levels o... Closed

 Description   

Result:

PDOException: SQLSTATE[HY000]: General error: 1 no such column: e2_.owner_id

Generated SQL:

SELECT c0_.id AS id0, c0_.createdAt AS createdAt1, c0_.updatedAt AS updatedAt2, c0_.title AS title3, c0_.color AS color4, c0_.owner_id AS owner_id5 FROM calendar c0_ INNER JOIN user u1_ ON e2_.owner_id = u1_.id WHERE u1_.username = 'bot'

Notice how the table alias "e2" does not existm yet is used in the join clause.

Meta:

/**

  • @ManyToOne(targetEntity="User")
  • @JoinColumn(name="owner_id", referencedColumnName="id")
    *
  • @var User
    */

DQL:

SELECT c FROM Calendar c JOIN c.owner u WHERE u.username = 'bot'

A workaround would be appreciated.

Thanks!



 Comments   
Comment by John Kleijn [ 17/Oct/10 ]

This also happened with BETA1 and also in other scenarios, e.g.

SELECT w0_.id AS id0, w0_.createdAt AS createdAt1, w0_.updatedAt AS updatedAt2, w0_.start AS start3, w0_.end AS end4, w0_.owner_id AS owner_id5 FROM worklog w0_ INNER JOIN user u1_ ON e2_.owner_id = u1_.id WHERE u1_.id = ? AND w0_.start IS NULL

SQLSTATE[HY000]: General error: 1 no such column: e2_.owner_id

This may have to do with the "owner" field being defined in a mapped superclass.

Comment by John Kleijn [ 17/Oct/10 ]

Confirmed, when I move the declaration down to the implementation class the exception goes away.

When I add it rather then moving it, I get an exception saying the field was already added, so the declaration in the supertype is not simply omitted (not that that would explain the invalid SQL).

Comment by Roman S. Borschel [ 17/Oct/10 ]

Generall,y mapped superclasses may only define unidirectional associations, because an association can not point back to a mapped superclass (a mapped superclass is not a persistent class). The relevant doc section is here: http://www.doctrine-project.org/projects/orm/2.0/docs/reference/inheritance-mapping/en#mapped-superclasses

Though, in your example the association actually points back to an entity, not the mapped superclass, so this may be a case that can be addressed properly, so we need to investigate this further.

ps: It is not entirely clear from the information you provided, but I assume there is no class that has targetEntity="NameOfMappedSuperclass" ? Because that will by definition never work.

Comment by John Kleijn [ 17/Oct/10 ]

No, there are no associations to the mapped superclass.

It is purely for defining common meta data and properties for a certain type, exactly what one would use a mapped superclass for.

It's worth noting that while this is a birectional association between the two types when viewed statically, we're not talking about a single, bidirectional relation:

  • Calendar has an owner, which is a User. This is the user that created the object, a mechanism applicable to most entities in the system, hence the mapped superclass.
  • A User has a Calendar, but he may or may not be the "owner" of that Calendar.

So User has this specified:

/**

  • @ManyToOne(targetEntity=Calendar", fetch="EAGER", cascade= {"persist", "remove"}

    )

  • @JoinColumn(name="calendar_id", referencedColumnName="id")
    *
  • @var Calendar
    */
    private $calendar;
Comment by John Kleijn [ 17/Oct/10 ]

Obviously this means that a User also has an "owner", which may or may not be the object itself.

Comment by Benjamin Eberlei [ 29/Oct/10 ]

I think this might be fixed with DDC-671 already.

Comment by Benjamin Eberlei [ 31/Oct/10 ]

relating

Comment by Benjamin Eberlei [ 31/Oct/10 ]

I need the whole entitiy definitions of Calender and User. Can you please paste them to somewhere?

Comment by Benjamin Eberlei [ 31/Oct/10 ]

I cannot reproduce it, i am pretty sure its a duplicate of DDC-671 and should therefore be fixed already in trunk.

Comment by John Kleijn [ 31/Oct/10 ]

> I need the whole entitiy definitions of Calender and User. Can you please paste them to somewhere?

I have since chaned it, but I emailed you what I think are the relevant revisions of the classes.

Comment by John Kleijn [ 02/Feb/11 ]

I've had a similar issue with multiple levels of MappedSuperclasses. It works in RC1, fails in 2.0 stable on non-existent table aliases. Don't have time to do a full bug report right now.





[DDC-736] Nasty ordering issue with fetch-joins Created: 07/Aug/10  Updated: 10/Dec/10  Resolved: 13/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA3
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Critical
Reporter: Roman S. Borschel Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File ddc736-simplified.patch     Text File ddc736.patch     File DDC736Test.php    
Issue Links:
Reference
is referenced by DDC-915 Breaks with Fixing Identification Var... Resolved
is referenced by DDC-925 Breaks with Fixing Identification Var... Resolved

 Description   

Will not work correctly:

select c, ca from Cart ca join ca.customer c

Works correctly:

select ca, c from Cart ca join ca.customer c

In the first case the ordering of the DQL aliases causes associations to be skipped during hydration.



 Comments   
Comment by Roman S. Borschel [ 30/Aug/10 ]

Scheduling for RC1.

Comment by Tim Oram [ 15/Oct/10 ]

If anyone is getting issues with missing or incorrectly ordered relations it may be caused by this bug.

Would it be possible to put a note in the documentation to ensure the order of the select clause must match that of the joins. I just spent 2 days trying to figure out why the data being returned was incorrect.

Comment by Benjamin Eberlei [ 10/Nov/10 ]

Patch that solves this problem. What does it do?

Two additional instance variables are needed, one for the order of the AliasIdentificationVariables and one for a IdentVariable => SelectExpression lookup map.

Inside parse() a reordering is done right before the SQL Walkers are created. This is only done if there is more than one Identification variable in the select expressions, otherwise its not necessary.

The reordering iterates in order of the alias identification variables, grabs the expression from the select expressions and appends it to them. This way it is guaranteed that the expressions are ordered correctly.

SELECT a, b, c.foo, count(d.bar) FROM B b JOIN b.a a JOIN ...

becomes:

SELECT c.foo, count(d.bar), b, a FROM ...

Roman do you think this is viable? See the patch for more details

Comment by Roman S. Borschel [ 12/Nov/10 ]

Attached simplified patch.

Comment by Benjamin Eberlei [ 13/Nov/10 ]

Fixed.

Comment by Mikko Hirvonen [ 07/Dec/10 ]

I think that this patch breaks modifying the select clause in custom tree walkers because walking the select clause will be done after the $_identVariableExpressions array is populated. Reordering the identification variables will then override the modified select clause.





[DDC-899] Add an unobtrusive way to determine if entity manager is closed Created: 29/Nov/10  Updated: 03/Dec/10  Resolved: 03/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Improvement Priority: Major
Reporter: Alexander Brouwer Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

There is no way to unobtrusively determine if an entity manager instance has been closed (due to exceptions/errors during a transaction).

Something like the following would come in handy:

class EntityManager {
public function isOpen()

{ return $this->closed === false; }

}

To determine if the instance is closed or not, this way one could instantiate a new entity manager instance with the same connection and configuration.



 Comments   
Comment by Benjamin Eberlei [ 03/Dec/10 ]

Implemented





[DDC-909] Doctrine 2 AbstractQuery:: _getResultCacheId() fails when an Entity instance is used as a param (recursive references and var_export don't mix) Created: 02/Dec/10  Updated: 03/Dec/10  Resolved: 03/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Daniel Cousineau Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Debian, PHP 5.3, Doctrine 2.0-BETA4



 Description   

In the AbstractQuery::_getResultCacheId() function the following line generates the MD5 hash key:

            return md5(implode(";", (array)$sql) . var_export($this->_params, true) .
                var_export($this->_hints, true)."&hydrationMode=".$this->_hydrationMode);

The issue is the use of var_export($this->_params, true); fails when one of the params is an instance of an Entity (which usually have recursive references).

To be honest I really don't know what solution there would be internally, if doctrine were to extend the proxy class to provide a "getIdentifier" or if the _getResultCacheId() could grab the identification of the Entity we could avoid this.

However beyond that potential idea really probably the best thing is to throw a giant warning text in the manual saying "if your'e using entities as parameters manually set your cache ids".



 Comments   
Comment by Daniel Cousineau [ 02/Dec/10 ]

Maybe serializing instead of running a var_export?

Comment by Daniel Cousineau [ 02/Dec/10 ]

Yeah, changing the var_export($this->_params, true) to serialize($this->_params) has yet to result in the same recursion error.

Comment by Benjamin Eberlei [ 03/Dec/10 ]

Its unbelievable slow though. I have to change this to retrieve the entity-identifer + name from the UoW

Comment by Benjamin Eberlei [ 03/Dec/10 ]

Fixed

Comment by Daniel Cousineau [ 03/Dec/10 ]

You get a high five, Benjamin!





[DDC-897] Make ClassMetadataFactory configurable Created: 27/Nov/10  Updated: 29/Nov/10  Resolved: 27/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

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


 Description   

It was requested lots of times: ClassMetadataFactory has to be overrideable for some frameworks to operate!



 Comments   
Comment by Benjamin Eberlei [ 27/Nov/10 ]

Implemented

Comment by ayhan [ 29/Nov/10 ]

that's really great news.

but i think, the access levels of its class properties and methods should be changed from private to protected or is there are reason for not doing that?
It would make it easier to subclass it, if you p.e. only want to override one method.

Comment by Benjamin Eberlei [ 29/Nov/10 ]

No, the only methods that should be overwritten are already protected or public.

Comment by ayhan [ 29/Nov/10 ]

thanks for the quick answer.

examples:

  • method getMetadataFor is public and probably candidate #1 to get overwritten... but that's only possible to a certain degree as the subclass cannot access the EntityManager.
  • method getAllMetadata is public, but as the subclass cannot access the initialized property, not really overwrittable.

i might have overlooked something, as i just grabbed the updated version.

Comment by Benjamin Eberlei [ 29/Nov/10 ]

no, the primary method to be overwritten are:

protected function newClassMetadataInstance($className)
protected function getParentClasses($name)

All the other code should not be touched as it handles the caching loading and such.

Comment by ayhan [ 29/Nov/10 ]

for me it's getMetadataFor :-D as i need another alias mechanism.

but don't get me wrong, i think the changes you already made are sufficent for my case... but it's confusing, therefore the comment.

for the method getParentClasses that you mentioned:

how would you access the driver property in the subclass?





[DDC-818] MSSQL Locking not working in all places Created: 26/Sep/10  Updated: 27/Nov/10  Resolved: 27/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

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


 Description   

MSSQL locking requires the table name to be hinted with additional information. However in many places there are only ways to append the lock hints to the whole Query.

We have to lock over the code and delegate table name generation to $platform->appendLockHint($tableName) to get this fixed.



 Comments   
Comment by Benjamin Eberlei [ 27/Nov/10 ]

This was fixed by juokaz





[DDC-880] Metadata XSD is out of sync Created: 16/Nov/10  Updated: 27/Nov/10  Resolved: 27/Nov/10

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

Type: Bug Priority: Minor
Reporter: Johannes Schmitt Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

The XSD file at http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd is out of sync with the git repository.



 Comments   
Comment by Benjamin Eberlei [ 27/Nov/10 ]

Fixed, however not in the deployment task (yet).





[DDC-876] CLI Global namespace forced on all Entity generated TypeHinting Created: 12/Nov/10  Updated: 27/Nov/10  Resolved: 27/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Minor
Reporter: Dirk Teurlings Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

All, but testcase on Debian Lenny (x64/32bit) with Squeeze php packages



 Description   

When using the CLI tool to generate your entities Doctrine forces a global namespace on all TypeHints in functions. For example I used the sandbox

See file User.php with function setAddress:

  1. public function setAddress(Address $address)

Remove this function entirely, so that it can be generated. Then run,

  1. ./doctrine orm:generate-entities .

Open file User.php and now the function has become:

  1. public function setAddress(\Address $address)

note the prepended \ for global namespace

This behaviour would be fine if all types would be in the global scope, but they're not. If you use another entity such as Address in the same namespace it should just generate the proper
public function setAddress(Address $address)

Or better yet, generate the Fully Qualified Namespace

Code responsible for this:
http://trac.doctrine-project.org/browser/trunk/lib/Doctrine/ORM/Tools/EntityGenerator.php#L609



 Comments   
Comment by Benjamin Eberlei [ 13/Nov/10 ]

sorry but the code you highlight here on trac is 7 months old, the current code is on Git: www.github.com/doctrine/doctrine2

Are you really using Beta 4?

Comment by Dirk Teurlings [ 13/Nov/10 ]

yes I'm using beta 4 It's a PEAR install.

Sorry for the outdated URL, here's the proper one.

https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/EntityGenerator.php#L591

Comment by Benjamin Eberlei [ 27/Nov/10 ]

Ah i know what is causing this issue.

The Disconnected Metadata factory cannot know which namespace the class is in. Are you generating the code from XML or YAML?

Comment by Dirk Teurlings [ 27/Nov/10 ]

No XML or YAML in this setup, just class files and an SQL based backend

Comment by Benjamin Eberlei [ 27/Nov/10 ]

Fixed





[DDC-895] Generated XML is not valid (because of order) Created: 27/Nov/10  Updated: 27/Nov/10  Resolved: 27/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: Git Master
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Benjamin Eberlei Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None


 Description   

The generated XML using the Tool Chain is not valid (because of order of generated elements).



 Comments   
Comment by Benjamin Eberlei [ 27/Nov/10 ]

Fixed.





[DDC-888] PHP stars to complain if no joinColumns/inverseJoinColumns provided for JoinTable annotation Created: 23/Nov/10  Updated: 27/Nov/10  Resolved: 27/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Improvement Priority: Trivial
Reporter: Sergei Lissovski Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

The problem is rather trivial - if no joinColumns or inverseJoinColumns provided for the JoinTable annotation declaration, then PHP will complain on lines 215/225 of Doctrine\ORM\Mapping\Driver\AnnotationDriver. The easiest way to eliminate this problem is to simply initialize these fields in the annotation-class:

DoctrineAnnotations.php
final class JoinTable extends Annotation {
    public $name;
    public $schema;
    public $joinColumns = array();
    public $inverseJoinColumns = array();
}


 Comments   
Comment by Benjamin Eberlei [ 27/Nov/10 ]

Fixed





[DDC-855] [patch] EntityGenerator add an extra return line at each call ... Created: 03/Nov/10  Updated: 27/Nov/10  Resolved: 27/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Thomas Rabaix Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

When using the php kooqit/console doctrine:generate:entities command (from the symfony2 framework), the EntityGenerator add an extra return line every time the command is called ....

diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index f2fa583..b0c8320 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -218,7 +218,7 @@ public function <methodName>()
         $body = str_replace('<spaces>', $this->_spaces, $body);
         $last = strrpos($currentCode, '}');
 
-        return substr($currentCode, 0, $last) . $body . "\n}";
+        return substr($currentCode, 0, $last) . $body . (strlen($body) > 0 ? "\n" : ''). "}";
     }
 
     /**



 Comments   
Comment by Benjamin Eberlei [ 27/Nov/10 ]

Fixed.





[DDC-882] The constructor type hinting of LoadClassMetadataEventArgs is not good Created: 18/Nov/10  Updated: 18/Nov/10  Resolved: 18/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Thomas Rabaix Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

symfony2 framework



 Description   

The constructor type hinting of LoadClassMetadataEventArgs is not good. It should be ClassMetadataInfo and not ClassMetadata.

ClassMetadataInfo is the base class used in the DisconnectedClassMetadataFactory. So when the event is used the argument is ClassMetadataInfo instance and not a ClassMetadata instance. I have this issue with the DoctrineBundle form the symfony2 framework.



 Comments   
Comment by Benjamin Eberlei [ 18/Nov/10 ]

Fixed





[DDC-722] EntityRepository::find(One?)By should also support Associations Created: 28/Jul/10  Updated: 16/Nov/10  Resolved: 16/Nov/10

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

Type: Improvement Priority: Minor
Reporter: Guilherme Blanco Assignee: Guilherme Blanco
Resolution: Fixed Votes: 0
Labels: None


 Description   

We should allow EntityRepository to also support associations fetching (when fetched Entity is the owning side).

$employee = $em->getRepository('Employee')->findByEmployer($em->getReference('Employer', $id));


 Comments   
Comment by Guilherme Blanco [ 16/Nov/10 ]

Already implemented.





[DDC-796] Inheritance Discriminator mapping fails when the parent class is after a subclass alphabetically Created: 09/Sep/10  Updated: 16/Nov/10  Resolved: 16/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Daniel Moore Assignee: Benjamin Eberlei
Resolution: Duplicate Votes: 0
Labels: None
Environment:

PHP 5.3, PDO_MYSQL


Attachments: File nonworking.rar     File working.rar    

 Description   

If I have a class called AbstractPage, with this single table inheritance mapping linking to the folllowing classes (Page, Article, Review), then it works fine:

<discriminator-column name="discr" type="string" />
<discriminator-map>
<discriminator-mapping value="page" class="Page" />
<discriminator-mapping value="article" class="Article" />
<discriminator-mapping value="review" class="Review" />
</discriminator-map>

If however I rename the classes to the Zend framework format, within modules (Default_Model_AbstractPage, Default_Model_Page, Article_Model_Article, Article_Model_Review), then because Article is before Default, then the schema tool gets confused and throws an error - [Doctrine\DBAL\Schema\SchemaException] The table with name 'pages' already exists. Everything else is the same but the class names.

I have attached examples of this both working and nonworking with the different naming schemes. As you can see everything else is the same.



 Comments   
Comment by Benjamin Eberlei [ 10/Sep/10 ]

if yo uspecify class="page" the class has to be called Page, not Default_Model_Page. You have to change the mapping to:

<discriminator-column name="discr" type="string" />
<discriminator-map>
<discriminator-mapping value="page" class="Default_Model_Page" />
<discriminator-mapping value="article" class="Default_Model_Article" />
<discriminator-mapping value="review" class="Default_Model_Review" />
</discriminator-map>

You cannot re-use the mapping for different classes, it has to be bound specifically to an exisiting class.

Comment by Daniel Moore [ 10/Sep/10 ]

I probably wasn't being explicit enough - when I said I rename the classes I also meant that I renamed them in all of the mapping, so I've got this:

<discriminator-column name="discr" type="string" />
<discriminator-map>
<discriminator-mapping value="page" class="Default_Model_Page" />
<discriminator-mapping value="article" class="Article_Model_Article" />
<discriminator-mapping value="review" class="Article_Model_Review" />
</discriminator-map>

And I've also renamed the mapping files themselves from Page.dcm.xml to Default_Model_Page.dcm.xml and so on. Still doesn't work.

Comment by Daniel Moore [ 10/Sep/10 ]

I've found a workaround for now. Move the subclasses into another folder (I've create a subfolder called "subclasses") and then add the second line:

$driverImpl = new Doctrine\ORM\Mapping\Driver\XmlDriver(_DIR_ . '/mappings');
$driverImpl->addPaths(array(_DIR_ . '/mappings/subclasses'));

That way the second folder will get read after the parent classes.

Comment by Benjamin Eberlei [ 16/Nov/10 ]

This issue was fixed in another ticket.





[DDC-511] Schema tool does not support STI - attempts to create a table per subclass Created: 10/Apr/10  Updated: 16/Nov/10  Resolved: 16/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA1
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: David Abdemoulaie Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Reference
relates to DDC-477 Schema tool does not support STI - at... Resolved

 Description   

A recent update broke all support for STI.

Now the following does not work:

/**
 * @MappedSuperclass
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"User" = "User", "Group" = "Group"})
 * @Table(name="user")
 */
abstract class Principal
{}
/**
 * @Entity
 */
class Group extends Principal
{}
/**
 * @Entity
 */
class User extends Principal
{}

Attempting to use orm:schema-tool:create results in the following error:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Group (user_id INT NOT NULL, username VARCHAR(45) NOT NULL, password VARCHAR(40)' at line 1

The SQL generated is:

CREATE TABLE Group (user_id INT NOT NULL, username VARCHAR(45) NOT NULL, password VARCHAR(40) NOT NULL, status SMALLINT NOT NULL, firstname VARCHAR(45) NOT NULL, lastname VARCHAR(45) NOT NULL, email VARCHAR(60) NOT NULL, phone VARCHAR(20) DEFAULT NULL, pager VARCHAR(20) DEFAULT NULL, reset_code VARCHAR(6) DEFAULT NULL, is_password_expired TINYINT(1) NOT NULL, failed_login_count SMALLINT NOT NULL, is_admin TINYINT(1) NOT NULL, version INT DEFAULT 1 NOT NULL, UNIQUE INDEX Group_username_uniq (username), PRIMARY KEY(user_id)) ENGINE = InnoDB;

CREATE TABLE User (user_id INT NOT NULL, username VARCHAR(45) NOT NULL, password VARCHAR(40) NOT NULL, status SMALLINT NOT NULL, firstname VARCHAR(45) NOT NULL, lastname VARCHAR(45) NOT NULL, email VARCHAR(60) NOT NULL, phone VARCHAR(20) DEFAULT NULL, pager VARCHAR(20) DEFAULT NULL, reset_code VARCHAR(6) DEFAULT NULL, is_password_expired TINYINT(1) NOT NULL, failed_login_count SMALLINT NOT NULL, is_admin TINYINT(1) NOT NULL, version INT DEFAULT 1 NOT NULL, UNIQUE INDEX User_username_uniq (username), PRIMARY KEY(user_id)) ENGINE = InnoDB;



 Comments   
Comment by Guilherme Blanco [ 12/Apr/10 ]

That seems to be a reserved keyword issues.
I see comments around the STI issues, but this one doesn't seem to be the case.

Try to use a different table name:

@Table(name="groups")

and...

@Table(name="users")

This should fix the issue.

Cheers,

Comment by David Abdemoulaie [ 12/Apr/10 ]

No. This is a STI problem. I don't want two different tables. Users and Groups are meant to share the same table "user". This worked prior to the omega CLI changes.

Comment by Roman S. Borschel [ 19/Apr/10 ]

After thinking about this a while, I think it is an interesting problem that points out some conceptual issues as well as some opportunities. The reason SchemaTool behaves that way is simple, I think: A mapped superclass is nothing more than a regular php class that inherits its mapping information to the child classes "as if it were defined directly on the child classes". It is mainly a way to "reuse" mapping information without copy/paste. So the example given in the issue description is pretty much the same as this:

abstract class Principal
{}
/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"User" = "User", "Group" = "Group"})
 * @Table(name="user")
 */
class Group extends Principal
{}
/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"User" = "User", "Group" = "Group"})
 * @Table(name="user")
 */
 */
class User extends Principal
{}

Hence why it wants to create two tables. However, something else is also probably wrong because it should rather result in an error due to creating the same table twice ("user"). So deriving @Table from a mapped superclass seems to be uncharted territory also. How/Why this ever worked before as you say is still a mystery to me. Do you know by any chance a revision or tag (alpha4?) where this worked so that we can compare to that?

As you already found out, making the parent class an @Entity should work fine. We need to think more about how to deal with inheritance mapping information derived from mapped superclasses. For example, what should happen if we take the original example in the issue description but use JOINED instead like this:

/**
 * @MappedSuperclass
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"User" = "User", "Group" = "Group"})
 */
abstract class Principal
{}
/**
 * @Entity
 */
class Group extends Principal
{}
/**
 * @Entity
 */
class User extends Principal
{}

Can this ever work or does it even make sense? Rewriting it to reflect what it actually "looks like" for Doctrine:

abstract class Principal
{}
/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"User" = "User", "Group" = "Group"})
 */
class Group extends Principal
{}
/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({"User" = "User", "Group" = "Group"})
 */
class User extends Principal
{}

I think this would make no sense at all. Hence the combination of @MappedSuperclass + @InheritanceType probably only seems to make sense currently in the SINGLE_TABLE scenario mentioned in the issue description.

An interesting possibility I noticed due to this ticket is that you can indeed use different inheritance mapping strategies in the same hierarchy, as long as the different subtrees of the hierarchy that are mapped with different strategies do not have a common ancestor entity. (For Doctrine the subtrees are then simply unrelated hierarchies, it does not care about common ancestor classes that are regular php classes). We should write some tests for that and add it to the docs, I will create a new ticket for that. Example:

class Base {}
class RootOfTreeA extends Base {} // Entity + SINGLE_TABLE
class RootOfTreeB extends Base {} // Entity + JOINED
Comment by Roman S. Borschel [ 30/Aug/10 ]

A solution and/or documented behavior for this should be evaluated before entering RC1.

Comment by Benjamin Eberlei [ 16/Nov/10 ]

MappedSuperclass Inheritance Details are confusing and are ignored now.





[DDC-853] Mysql: Drop schema for entities doesnt work if Database contains already tables with 'enum' Field Created: 01/Nov/10  Updated: 16/Nov/10  Resolved: 16/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Christian Steinmann Assignee: Roman S. Borschel
Resolution: Duplicate Votes: 0
Labels: None
Environment:

Win 7 64Bit; PHP 5.3.3, MYSQL 5.14



 Description   

Dropping Entities with:

$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
$classes = array(
  $em->getClassMetadata('Entities\User'),
  $em->getClassMetadata('Entities\Profile')
);
$tool->dropSchema($classes);

throws:
Doctrine\DBAL\DBALException: Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it

The Database already contains some tables with enum fields. But those should not be affected. They have no constraints to the tables managed by the EntityManager

Some debugging brought me to the point that Doctrine2 is trying to drop complete database, even metaclasses where given.

In Doctrine\ORM\Tools\SchemaTool $classes will not be used in any way

    public function dropSchema(array $classes)
    {
        $dropSchemaSql = $this->getDropSchemaSql($classes);
        $conn = $this->_em->getConnection();

        foreach ($dropSchemaSql as $sql) {
            $conn->executeQuery($sql);
        }
    }
// Here $classes will not be used
    public function getDropSchemaSql(array $classes)
    {
        $sm = $this->_em->getConnection()->getSchemaManager();
        $schema = $sm->createSchema();

        $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform);
        /* @var $schema \Doctrine\DBAL\Schema\Schema */
        $schema->visit($visitor);
        return $visitor->getQueries();
    }

Also method SchemaTool::_getDropSchemaTablesDatabaseMode($classes) seems not to be used.



 Comments   
Comment by Benjamin Eberlei [ 16/Nov/10 ]

Fixed, duplicate of DDC-629





[DDC-629] SchemaTool's method dropSchema, drops all classes instead of those specified in $classes argument Created: 09/Jun/10  Updated: 16/Nov/10  Resolved: 16/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA1
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Joshua Henn Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 1
Labels: None
Environment:

Ubuntu, PHP 5.3.2, MySQL



 Description   
$classes = array(
  $this->_em->getClassMetadata('Models\Acl\Role'),
  $this->_em->getClassMetadata('Models\Acl\Resource\Module'),
  $this->_em->getClassMetadata('Models\Acl\Resource\Controller'),
  $this->_em->getClassMetadata('Models\Acl\Resource\Action')
);

// Delete databases
$tool = new \Doctrine\ORM\Tools\SchemaTool($this->_em);
$tool->dropSchema($classes);

Expected:
Drops just schema specified by $classes

Actual:
Drops all schema, not just that specified in $classes



 Comments   
Comment by Joshua Henn [ 11/Jun/10 ]

SchemaTool.php method getDropSchemaSql(array $classes)

doesn't create $schema from $classes argument
$schema = $sm->createSchema();

Additionally in AbstractSchemaManager.php method createSchema() ..

doesn't support creating schema from argument ($classes)

Comment by Benjamin Eberlei [ 11/Jun/10 ]

yeah i think this is a non-issue, but requires better documentation and a disctiction of th etwo different approaches to deleting tables through totally different method names. I will be on this issue

Comment by Benjamin Eberlei [ 16/Nov/10 ]

fixed





[DDC-867] QueryBuilder clone only does shallow clone Created: 08/Nov/10  Updated: 15/Nov/10  Resolved: 15/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Brandon Turner Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

Cloning a QueryBuilder object only performs a shallow clone. This is problematic as object references in the dqlParts array stay the same in cloned copies of a QueryBuilder object.

For example, say I have a QueryBuilder object with two simple "andWhere" clauses. Now I clone the QueryBuilder instance and add a third "andWhere" clause to the cloned object. The 3rd andWhere clause will also appear in the original QueryBuilder object. The desired behavior is that the original QueryBuilder object is not modified when adding clauses to the cloned copy.



 Comments   
Comment by Benjamin Eberlei [ 15/Nov/10 ]

Fixed





[DDC-866] The EBNF definition for DQL needs to be updated Created: 08/Nov/10  Updated: 15/Nov/10  Resolved: 15/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Daniel Alvarez Arribas Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

This is a summary replacing bugs 857, 863 and 864, which I hereby close.

In summary, deep path expressions like

SingleValuedAssociationPathExpression ::= IdentificationVariable "."

{SingleValuedAssociationField "."}

* SingleValuedAssociationField

are not suppored by the current implementation, but are documented to work in the EBNF definition for DQL (http://www.doctrine-project.org/projects/orm/2.0/docs/reference/dql-doctrine-query-language/en#dql-doctrine-query-language). The EBNF definitions need to be fixed, because currently they are factually wrong and thus misleading.

(Obviously, actually having the feature would be preferrable IMO)



 Comments   
Comment by Benjamin Eberlei [ 09/Nov/10 ]

This feature was removed for technical reasons. I updated the docs accordingly.

Comment by Daniel Alvarez Arribas [ 15/Nov/10 ]

The online documentation (http://www.doctrine-project.org/projects/orm/2.0/docs/reference/dql-doctrine-query-language/en#dql-doctrine-query-language) is still listing the factually wrong EBNF, specifically:

/* "u.Group" */
SingleValuedAssociationPathExpression ::= IdentificationVariable "."

{SingleValuedAssociationField "."}* SingleValuedAssociationField

/* "u.Group.Permissions" */
CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}

* CollectionValuedAssociationField

I cleared my local web cache, of course, before viewing, but to no effect. It's possibly that the fix was done internally in a SCM Tool, but was not published. As of now, the documentation fix did not become effective for the docs that are now visible online. I reopen this as a reminder.

Comment by Benjamin Eberlei [ 15/Nov/10 ]

we dont render the docs all the time, it takes some time.





[DDC-873] @Version and Single Table Created: 10/Nov/10  Updated: 11/Nov/10  Resolved: 11/Nov/10

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

Type: Improvement Priority: Major
Reporter: Timo A. Hummel Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

In my previous Bug Report DDC-871 I'm using a separate table for versioning copies. However, if one wishes to keep all versions in a single table, this causes some headaches, since the field with @version can't be set by the developer (i.e. Doctrine2 does magic here).

I'll try to describe it with some meta code.

Let's say you have the class SingleTable, which has a property version marked with @version and @id, and also a property id marked with @id. I know this isn't the preferred way since it's a composite primary key, but in theory it would work. I'm managing the ID of the object myself, which works without a problem.

The problem is that once a field is marked with @version, it isn't set during an insert operation. Doctrine2 relies on the field's default value. This causes the following problems:

  • You can't start with an object version higher than 1.
  • If you wish to insert an older version (which is possible with my composite primary key example), you can't simply set the version - Doctrine2 does it's own magic, which fails at this point.

No matter if there will be a change to the @version behavior or not, it should be documented a bit better in the documentation. Once I know if it will be changed or not, I can contribute additional documentation for this.



 Comments   
Comment by Benjamin Eberlei [ 10/Nov/10 ]

Yes @Version and @Id are not allowed. This should just throw an exception.

Comment by Timo A. Hummel [ 10/Nov/10 ]

As I'm already working on some documentation things, I will add this to the documentation and maybe also add some code to throw an Exception.

Comment by Timo A. Hummel [ 10/Nov/10 ]

Just created a pull request for this (I added the bugfix + testcase), feel free to close after pull.

Comment by Benjamin Eberlei [ 11/Nov/10 ]

Implemented exception on this wrong usage.





[DDC-856] Boolean discriminator field for single table inheritance does not work as expected with MySQL Created: 03/Nov/10  Updated: 11/Nov/10  Resolved: 11/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: seba kerckhof Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

MySQL 5



 Description   

Hello,

I have a a single table inheritance, with a boolean discriminator field, see: http://pastie.org/1269467
As MySQL does not have a boolean field, true / false should be translated to 1/0 (as it uses a TINYINT(1) field instead).

If I use 1 / 0 in the annotation instead of true / false it works, but than it's not boolean anymore...

So it should either translate that, or mention this in the documentation (although vendor specific exceptions should be avoided imo).



 Comments   
Comment by Benjamin Eberlei [ 04/Nov/10 ]

This is not supported, i suggest using smallint and 0 / 1 instead.

Comment by Benjamin Eberlei [ 11/Nov/10 ]

Throwing an exception now on using boolean, object, array, datetime, date or time for the discriminator column.





[DDC-870] @Version causes integer fields to return a string Created: 09/Nov/10  Updated: 09/Nov/10  Resolved: 09/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Timo A. Hummel Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

Here's a small example when using @Version causes the field to return a string and not an integer.

Here's a very simple example:

SimpleTest class
/**
 * @Entity
 */
class SimpleTest {
	 /**
     * @Id
     * @generatedValue(strategy="AUTO")
     * @Column(type="integer")
     */
    private $id;
    /**
     * @Column(type="integer")
     * @version
     */
    private $version;
    /**
     * @Column
     */
    private $content;
    
    public function setContent ($content) {
    	$this->content = $content;
    }
    
    public function getVersion () {
    	return $this->version;
    }
    
    public function getId () {
    	return $this->id;
    }
    
}
Invocation
$test = new SimpleTest();
$test->setContent("V1");
$em->persist($test);
$em->flush();

if (gettype($test->getVersion()) == "string") { die("Version should be an integer, not a string!"); }

The invocation fails because the version property is suddenly a string and not an integer anymore.



 Comments   
Comment by Benjamin Eberlei [ 09/Nov/10 ]

Fixed, and a bunch of other issues with versioning that i found while looking at the code.





[DDC-868] ORM:Schema-tool:create failure -- the result depends on xml files enumeration order of RecursiveDirectoryIterator in context of SINGLE_TABLE inherantence Created: 08/Nov/10  Updated: 09/Nov/10  Resolved: 09/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Jim Chen Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows or Linux, PHP-5.3.3


Attachments: XML File Droop.Model.Drooplet.dcm.xml     XML File Droop.Model.Menu.dcm.xml     XML File Droop.Model.Sysbase.dcm.xml    

 Description   

= Relevant configuration: =
resources.doctrine.driver.class = Doctrine\ORM\Mapping\Driver\XmlDriver
resources.doctrine.driver.dir = APPLICATION_PATH "/../library/Droop/Model/Xml"
resources.doctrine.cache.class = Doctrine\Common\Cache\ArrayCache
resources.doctrine.conn.driver = pdo_mysql

= Models hierarchy =
class Sysbase {}
class Drooplet extends Sysbase {}
class Menu extends Sysbase {}

= Xml driver =
attached

= Error =
While using command line to generate schema [php doctrine.php orm:schema-tool:create --dump-sql], it reports error "The table with name 'system' already exists." on windows however not on linux.

It is because the ClassMetaFactory.php depends on the sequence of result returned by getAllClassNames(). In this scenario, it's in descending order on linux and ascending on windows.
124 foreach ($this->driver->getAllClassNames() as $className)

{ 125 $metadata[] = $this->getMetadataFor($className); 126 }

127
128 return $metadata;
This order populates to SchemaTool::getSchemaFromMetadata(); If the base model is processed before it's descendants, everything is OK. Otherwise, it will complain about the table already exists.

= Fix =
ClassMetaFactory.php
128 return $this->loadedMetadata;



 Comments   
Comment by Benjamin Eberlei [ 09/Nov/10 ]

By what means is that a valid fix? Doesnt that just give another random order that happens to work for your cases now?

Comment by Benjamin Eberlei [ 09/Nov/10 ]

Fixed





[DDC-861] Improve ProxyFactory to avoid having to use Autoloader Created: 05/Nov/10  Updated: 06/Nov/10  Resolved: 06/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

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


 Description   

In ProxyFactory::getProxy all the information is necessary to avoid having to configure an autoloader. Why don't we do that already?



 Comments   
Comment by Benjamin Eberlei [ 05/Nov/10 ]
diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/lib/Doctrine/ORM/Proxy/ProxyFactory.php
index 472e730..8be75d9 100644
--- a/lib/Doctrine/ORM/Proxy/ProxyFactory.php
+++ b/lib/Doctrine/ORM/Proxy/ProxyFactory.php
@@ -77,9 +77,11 @@ class ProxyFactory
         $proxyClassName = str_replace('\\', '', $className) . 'Proxy';
         $fqn = $this->_proxyNamespace . '\\' . $proxyClassName;
 
-        if ($this->_autoGenerate && ! class_exists($fqn, false)) {
+        if (! class_exists($fqn, false)) {
             $fileName = $this->_proxyDir . DIRECTORY_SEPARATOR . $proxyClassName . '.php';
-            $this->_generateProxyClass($this->_em->getClassMetadata($className), $proxyClassName, $fileName, self::$_proxyClassTemplate);
+            if ($this->_autoGenerate) {
+                $this->_generateProxyClass($this->_em->getClassMetadata($className), $proxyClassName, $fileName, self::$_proxyClassTemplat
+            }
             require $fileName;
         }
Comment by Benjamin Eberlei [ 06/Nov/10 ]

I committed this yesterday. From now you don't need an autoloader for both autogenerate = true and = false.





[DDC-860] loadClassMetadata event on event listeners Created: 05/Nov/10  Updated: 05/Nov/10  Resolved: 05/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: New Feature Priority: Minor
Reporter: Gediminas Morkevicius Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

no matter



 Description   

loadClassMetadata event arguments - LoadClassMetadataEventArgs, should contain a reference to metadataCacheDriver used on classMetadataFactory
that is important in order to cache additional metadata which can be read from other annotations during this event. Currently it is not possible to retrieve it during this event.
That concerns only event listeners not livecycle events directly on entity.



 Comments   
Comment by Benjamin Eberlei [ 05/Nov/10 ]

Implemented





[DDC-859] Datetime object changeset computing Created: 05/Nov/10  Updated: 05/Nov/10  Resolved: 05/Nov/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: New Feature Priority: Minor
Reporter: Gediminas Morkevicius Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None
Environment:

php 5.3.2, windows



 Description   

The problem is with Datetime value on entity, if I dirrecly modify it, unitOfWork will not add it into change set
// assume loaded entity through dql or repository:

$entity->getStartDate()->modify("+ 1day");
$em->persist($entity);
$em->flush(); // no changes

as far as I understand objects are compared through ($oldObject === $newObject) probably php takes spl_object_hash to do the comparison
copying an object works as expected



 Comments   
Comment by Benjamin Eberlei [ 05/Nov/10 ]

This is expected behavior, DateTime objects are thought of as immutable value objects (php allowing them to be mutable is sort of a design mistake that even Derick sees now).

Only changing the instance will change the value, otherwise the difference computation would be too difficult and would involve cloning the datetime (overhead).





[DDC-824] EntityManager::remove($entity), EntityManager::flush() does not remove the entity from DB Created: 02/Oct/10  Updated: 05/Nov/10  Resolved: 05/Nov/10

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

Type: Bug Priority: Critical
Reporter: Petr Motejlek Assignee: Benjamin Eberlei
Resolution: Invalid Votes: 0
Labels: None
Environment:

PgSQL 8.4, current Doctrine 2 from Git



 Description   
Test.php
/* 
 * @Entity
 * @Table(indexes={@Index(name="name", columns={"name"})})
 */
class ProductAttribute
{

    /**
     * ID
     * 
     * @Id @Column(type="integer") @GeneratedValue
     *
     * @var integer
     */
    protected $id;
    /**
     * Name
     *
     * @Column
     *
     * @var string
     */
    protected $name;
    /**
     * Values
     *
     * @OneToMany(targetEntity="ProductAttributeValue", mappedBy="attribute")
     *
     * @var array
     */
    protected $values;

    /**
     * Gets ID
     *
     * @return integer ID
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Sets ID
     *
     * @param integer $id ID
     *
     * @return void
     */
    public function setId($id = null)
    {
        $this->id = $id;
    }

    /**
     * Gets name
     *
     * @return string Name
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Sets name
     *
     * @param string $name Name
     *
     * @return void
     */
    public function setName($name = null)
    {
        $this->name = $name;
    }

    /**
     * Gets product attribute values
     *
     * @return array Product attribute values
     */
    public function getValues()
    {
        return $this->values;
    }

    /**
     * Adds product attribute value
     *
     * @param ProductAttributeValue $value Product attribute value
     * 
     * @return void
     */
    public function addValue(ProductAttributeValue $value)
    {
        $value->setAttribute($this);
        $this->values[] = $value;
    }

}

$attribute = $em->find('ProductAttribute', 1);
$em->remove($attribute);
$em->flush();

The upper code won't remove the entity from the database.... Corresponding DQL (DELETE ProductAttribute a WHERE a.id = 1) will remove it from the database...



 Comments   
Comment by Petr Motejlek [ 03/Oct/10 ]

I just found out, that when I have an entity containing a *ToMany column with cascade=

{"remove"}

set, all the entities are removed, except for the one...

Comment by Benjamin Eberlei [ 31/Oct/10 ]

I cannot reproduce this issue. Can you try to build a reproducible test-case? Have a look at tests/Doctrine/Tests/ORM/Functional/Ticket/* and build a test-case like this one here:

<?php

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsGroup;

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

class DDC824Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
    public function setUp()
    {
        $this->useModelSet('cms');
        parent::setUp();
    }

    public function testRemoveWithCascade()
    {
        $user = new CmsUser();
        $user->username = "beberlei";
        $user->name = "Benjamin";
        $user->status = "active";

        $phone1 = new \Doctrine\Tests\Models\CMS\CmsPhonenumber();
        $phone1->phonenumber = "1234";
        $phone2 = new \Doctrine\Tests\Models\CMS\CmsPhonenumber();
        $phone2->phonenumber = "1235";

        $user->addPhonenumber($phone1);
        $user->addPhonenumber($phone2);

        $this->_em->persist($user);
        $this->_em->flush();
        $this->_em->clear();

        $user = $this->_em->find(get_class($user), $user->id);
        $phone1 = $user->phonenumbers[0];
        $phone2 = $user->phonenumbers[1];

        $this->assertTrue($this->_em->contains($user));
        $this->assertTrue($this->_em->contains($phone1));
        $this->assertTrue($this->_em->contains($phone2));

        $this->_em->remove($user);

        $this->assertFalse($this->_em->contains($user));
        $this->assertFalse($this->_em->contains($phone1));
        $this->assertFalse($this->_em->contains($phone2));
    }
}
Comment by Petr Motejlek [ 04/Nov/10 ]

I found out that I cannot reproduce the same behaviour with different project of mine either. It seems there's simply something rotten inside the one. I'll try investigating it a bit farther, but I think you can close this issue for now. Thanks for your time .





[DDC-812] DQL hydration of joined objects skipped when main instance already present in entity manager Created: 21/Sep/10  Updated: 31/Oct/10  Resolved: 31/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Dennis Verspuij Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None


 Description   

I do the following:

$author1 = $em->find('Author', 1);

$author1again = $em
  ->createQuery(
    'SELECT A, B '.
    'FROM Author A '.
    'INNER JOIN A.Books B '.
   'WHERE A.ID = 1'
  )
  ->getSingleResult();

the Books collection is not hydrated because the author instance was already
hydrated when populating $author1. This means when I call
count($author1->getBooks()) a third query is executed to fetch the Books again.

The result is even more problematic when adding a WITH clause to the
INNER JOIN, in that case one would expect the Books collection to only
contain the books matching matching that criteria.

The result is expected when commenting out the $author1 =... line, thus when
the author does not already exist in the entity manager.

I'm sorry I can't produce a test case right now.



 Comments   
Comment by Benjamin Eberlei [ 21/Sep/10 ]

fix formatting

Comment by Roman S. Borschel [ 31/Oct/10 ]

Fixed in master. Note that your second case still "won't work" from your point of view. If the collection is already initialized it is not overridden. This is consistent with other behavior (what is in-memory is preserved). Fetch-joinining a collection and using WITH at the same time is not a nice thing to do since the meaning of the association is changed per-query. First $author->getBooks() means one thing (all books written by this author) and a few lines later something else (all books written by this author in the last 10 years or whatever). To get the desired result in your second case, that is, overriding the collection in-memory, set the REFRESH query hint. Note that this will change the meaning of Author#books though, as is always the case with fetch-join + WITH.





[DDC-826] Problem with @MappedSuperclass and associations Created: 06/Oct/10  Updated: 31/Oct/10  Resolved: 31/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA2
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Kristiyan Chakarov Assignee: Benjamin Eberlei
Resolution: Duplicate Votes: 0
Labels: None

Attachments: Zip Archive test.zip    
Issue Links:
Reference
is referenced by DDC-841 Generated SQL contains non-existen alias Resolved

 Description   

I have a project with global entities(Lib\Shared\Main - @MappedSuperclass ) and local entities(Shared\Main) which extends the globals.

The following DQL is returning wrong SQL:

SELECT Horoscope FROM Shared\Main\Horoscope Horoscope JOIN Horoscope.sign Sign WHERE Sign.id = 7

SELECT h0_.id AS id0, h0_.date AS date1, h0_.contents AS contents2, h0_.signId AS signId3 FROM horoscopes h0_ INNER JOIN global.sys_zodiac_signs g1_ ON h2_.signId = g1_.id WHERE g1_.id = 7

The attached zip contains the entity files.

What is the correct way to extends entities and to build JOINed requests

Have a nice day



 Comments   
Comment by Benjamin Eberlei [ 06/Oct/10 ]

Beta2? Please update to Beta4

Are you using YAML Driver? If yes this is a known bug that was fixed in trunk lately and will be included as a fix for RC1.

Comment by Kristiyan Chakarov [ 06/Oct/10 ]

I'm using annotations and Beta4 is not working better for my problem.

Comment by Kristiyan Chakarov [ 06/Oct/10 ]

is there a good example of using Class Table Inheritance and Mapped Superclasses

Comment by Benjamin Eberlei [ 31/Oct/10 ]

I cant reproduce it, i am pretty sure this is a duplicate of DDC-671





[DDC-671] Table aliases wrongly computed with YAML + mappedsuperclasses and joins Created: 06/Jul/10  Updated: 31/Oct/10  Resolved: 21/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA2
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Christian Heinrich Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Reference
is referenced by DDC-841 Generated SQL contains non-existen alias Resolved

 Description   

Affects only YAML. (Maybe also XML? But works with Annotations!)

If there's a relation specified in a mappedSuperclass (manyToOne, towards entity B) and two Entities A and B using this mappedSuperclass, an error occurs within generating the SQL-Query when using a query a la SELECT * FROM A JOIN B ON A.relation = B.id:

This is due to no table name being specified for the mappedSuperclass. (But this tableName is accessed in SqlWalker.php ll. 718. Be aware that there's the mappedSuperclass in use, NOT the class B!)

I'm not quite sure how this should be handled. At least, not specifying the relation in the mappedSuperclass but moving it to each of the yml-files of A and B solves this problem. (But unneccessarily complicates things?)

I will push a test case to my repo.



 Comments   
Comment by Christian Heinrich [ 06/Jul/10 ]

A testcase is now available in my repo: http://github.com/Shurakai/doctrine2/tree/DDC-671

Comment by Jonathan H. Wage [ 07/Aug/10 ]

According to the docs: http://www.doctrine-project.org/projects/orm/2.0/docs/reference/inheritance-mapping/en#inheritance-mapping

"A mapped superclass cannot be an entity, it is not queryable and persistent relationships defined by a mapped superclass must be unidirectional. For further support of inheritance, the single or joined table inheritance features have to be used."

Comment by Benjamin Eberlei [ 08/Aug/10 ]

I agree with Jon, this is not an issue.

I dont understand at all what this has to do with XML, YAML or Annotations?

Comment by Christian Heinrich [ 11/Aug/10 ]

Jonathan: Thanks for your comment, but that does not seem to fit the problem. As you can see within my testcase, the mapped superclass defines a relationship (manyToOne) which is unidirectional.

Benjamin: The problem is, that this specific feature works with annotations, but not with YAML.

Comment by Jonathan H. Wage [ 11/Aug/10 ]

When I look at your test I see you have association on the mapper super class side as well as on Directory side. That looks bidirectional, no?

Comment by Benjamin Eberlei [ 15/Aug/10 ]

@jwage he is specifiying a directory or page on the OneToMany side, so this looks ok.

@Christian: Why do you specified a table attribute on the mapped superclass? That doesnt make sense. The mapping looks correct, can you please show the error message? ADditionally can you link the correct line in SQL Walker again? The lines moved, so i cant verify what 718 is anymore, it changed.

Comment by Christian Heinrich [ 13/Sep/10 ]

Benjamin: I removed the table attribute on the mapped superclass. I don't know why it was in there.

Some more information:

The parentDirectory is currently in the mappedSuperclass. However, if you try to join it this way, the source entity used in SqlWalker::walkJoinVariableDeclarationwill look like this:

  ["sourceEntity"]=>
  string(46) "Doctrine\Tests\ORM\Mapping\AbstractContentItem"

Which is actually the mappingSuperclass.

That said, Doctrine will try to get an alias for AbstractContentItem (l. 730 SqlWalker), which does not exist at that point. Thus, it will create a new one (in my case: a2).

You can see the result in the query below. Note that a2 is only used, but never declared.

SELECT c0_.id AS id0, c0_.extension AS extension1, c0_.parent_directory_id AS parent_directory_id2 FROM core_content_pages c0_ INNER JOIN core_content_directories c1_ ON a2_.parent_directory_id = c1_.id WHERE (c1_.url = ?) AND (c0_.extension = ?)

It might be that l. 730 currently passes a wrong argument (mappedSuperclass instead of entity-in-use) or that there is some error in the yaml driver? As I'm unfortunately not too familiar with this process, I need your oppinions to fix this issue. It would be interesting to know where the

$this->_queryComponents[$joinedDqlAlias]['relation']

array is getting filled.

Comment by Benjamin Eberlei [ 21/Sep/10 ]

This is actually wrong for Annotations and XML Driver also, the problem is shown by this assertions and test-failures in combination with your test:

        $classPage = $em->getClassMetadata('Doctrine\Tests\ORM\Mapping\Page');
        $this->assertEquals('Doctrine\Tests\ORM\Mapping\Directory', $classPage->associationMappings['parentDirectory']['sourceEntity']);
        $classDirectory = $em->getClassMetadata('Doctrine\Tests\ORM\Mapping\Page');
        $this->assertEquals('Doctrine\Tests\ORM\Mapping\Directory', $classDirectory->associationMappings['parentDirectory']['sourceEntity']);

Failure.

1) Doctrine\Tests\ORM\Mapping\YamlMappingDriverTest::testJoinTablesWithMappedSuperclassForYamlDriver
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-Doctrine\Tests\ORM\Mapping\Directory
+Doctrine\Tests\ORM\Mapping\AbstractContentItem

/home/benny/code/php/wsnetbeans/doctrine2/tests/Doctrine/Tests/ORM/Mapping/YamlMappingDriverTest.php:33

2) Doctrine\Tests\ORM\Mapping\AnnotationDriverTest::testJoinTablesWithMappedSuperclassForAnnotationDriver
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-Doctrine\Tests\ORM\Mapping\Directory
+Doctrine\Tests\ORM\Mapping\AbstractContentItem
Comment by Benjamin Eberlei [ 21/Sep/10 ]

This works with annotations because the annotation reader also reads properties from parent classes.

For YAML and XML this did not work and required a little change in the ClassMetadataFactory method that copied over inherited metadata.





[DDC-758] When merging many to many entites back into the repository changes to the associations are not respected Created: 19/Aug/10  Updated: 31/Oct/10  Resolved: 31/Oct/10

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

Type: Bug Priority: Major
Reporter: Dave Keen Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 1
Labels: None

Attachments: Text File 0147-DDC-758.patch     File DDC758Test.php    

 Description   

When merging a DETACHED entity into the repository with ManyToMany associations that have changed since the last flush, the join table is not updated with the new associations.

Many Movies have many Artists with cascade merge:

class Movie {
	
	/** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
	public $id;
	
	/** @Column(length=50, type="string") */
	public $title;
	
	/** 
	 * @ManyToMany(targetEntity="Artist", cascade={"merge"})
	 */
	public $artists;
	
	public function __construct() {
		$this->artists = new ArrayCollection();
	}	

}
<?php
class Artist {
	
	/** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
	public $id;
	
	/** @Column(length=50, type="string") */
	public $name;
	
	/** @ManyToMany(targetEntity="Movie", mappedBy="artists", cascade={"merge"}) */
	public $movies;
	
	public function __construct() {
		$this->movies = new ArrayCollection();
	}
	
}

Assume that the database contains:
Movie: id=1, title="Movie 1"
Artist: id=1, name="Artist 1"
Artist: id=2, name="Artist 2"

and that there is a entry (1, 1) in movie_artist so that there is a many-many relationship between Movie 1 and Artist 1.

I now want to merge a detched version of a movie into the repository, with an extra relationship between Movie 1 and Artist 2:

$m1 = new \vo\Movie();
$m1->id = 1;
$m1->title = "Movie 1";

$a1 = new \vo\Artist();
$a1->id = 1;
$a1->name = "Artist 1";

$a2 = new \vo\Artist();
$a2->id = 2;
$a2->name = "Artist 2";

$m1->artists->add($a1); $a1->movies->add($m1);

// Add the new association
$m1->artists->add($a2); $a2->movies->add($m1);

// This is a cascade merge so it will merge the entities down the tree
$m1 = $em->merge($m1);

At this point $m1 should contains merged entities reflecting the same as what is in the database, plus the extra association between Movie 1 and Artist 2, so after a flush() movie_artist should contain (1,1),(1,2)

I now run:

$em->flush();

but movie_artist remains unchanged (still just (1,1)) and $em->getUnitOfWork()->computeChangeSets() is empty before the flush().

The same behaviour is exhibited when merging $m1 after deleting entities from its many-to-many associations; movie_artist does not change.



 Comments   
Comment by Dave Keen [ 13/Sep/10 ]

Here is a failing test case for this issue.

Comment by Dave Keen [ 13/Sep/10 ]

The problem area seems to be in the first lines of UnitOfWork::computeAssociationChanges:

if ($value instanceof PersistentCollection && $value->isDirty()) {
            if ($assoc['isOwningSide']) {
                $this->collectionUpdates[] = $value;
            }
            $this->visitedCollections[] = $value;
        }

If I comment out the check for $value->isDirty() then the test case passes so it looks like this is failing because the ManyToMany PersistentCollection isn't getting marked as dirty during computeChangeSets. I've actually fiddled around and found various ways to fix it, but computeChangeSets is pretty complicated and I'm worried that any changes I make might affect performance without me realizing. However, if you can give me a few pointers I'm happy to have another go at patching the issue.

Comment by Dave Keen [ 21/Sep/10 ]

As it turns out commenting out $value->isDirty() only half fixes the problem; it fixes it in the case of adding many to many associations (as in the example about), but it doesn't fix the case of removing many to many associations.

I have updated the attached test to include a test case which creates some many to many associations, then merges in equivalent detached entities but which have empty association attributes. On a cascade merge and flush I would expect this to empty out the associations table; in fact it has no effect.

Comment by Benjamin Eberlei [ 21/Sep/10 ]

removing $value->isDirty() is no option as it is really necessary at that position. The question is, why does merge not mark the collection as dirty.

Comment by Dave Keen [ 21/Sep/10 ]

Agreed. I am hard at work on this right now, and have discovered something that may be another clue. It actually seems the problem is twofold. As well as the collection not getting marked dirty, the reason that the ManyToManyPersister is not removing rows is that PersistentCollection::getDeleteDiff() isn't returning any differences, and the reason for that is that $snapshot isn't get set to anything during the merge process. When merging a collection I think we need to set $snapshot to whatever is currently in the database, and set $coll to whatever is in the collection being merged. I'm not quite sure, but perhaps this could also be the reason why the collection isn't getting set as dirty?

Comment by Dave Keen [ 21/Sep/10 ]

This is an attempt to patch the issue. After each cascade merge this fills in $snapshot from the database.

Comment by Dave Keen [ 21/Sep/10 ]

Slightly changed the patch - this uses setDirty() instead of changed() - without this a Flextrine test fails.

Comment by Benjamin Eberlei [ 31/Oct/10 ]

Fixed, can you verify Dave?





[DDC-666] @ManyToMany JoinTable defaults - Allow only table name Created: 04/Jul/10  Updated: 31/Oct/10  Resolved: 31/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA2
Fix Version/s: 2.0-RC1
Security Level: All

Type: Improvement Priority: Major
Reporter: Benjamin Eberlei Assignee: Roman S. Borschel
Resolution: Duplicate Votes: 1
Labels: None


 Description   

Currently you cannot only speciify the table name and rely on the mapping to figure out the foreign key names.

The following should be possible:

/**
 * @ManytoMany(targetEntity="Foo")
 * @JoinTable(name="foo_bar_table")
 */


 Comments   
Comment by Roman S. Borschel [ 07/Aug/10 ]

Scheduling for 2.1 for now.

Comment by Roman S. Borschel [ 30/Oct/10 ]

I think this is fixed already?

Comment by Benjamin Eberlei [ 31/Oct/10 ]

Yes, closed





[DDC-832] Not quoted class name when updating entity Created: 07/Oct/10  Updated: 30/Oct/10  Resolved: 30/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Critical
Reporter: Paul Fariello Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

postgresql 8.4 php 5.3.2


Issue Links:
Reference
relates to DBAL-57 Handling of Quoted Elements Open

 Description   

When trying to update an entity which have a reserved name. Doctrine doesn't quoted its name.

On Doctrine\ORM\Persisters\BasicEntityPersister, _updateTable, $tableName is directly used to create the sql. We may use $this->_class->getQuotedTableName($this->_platform) instead ?

I'm going to propose a merge for that on github.



 Comments   
Comment by Paul Fariello [ 08/Oct/10 ]

Here is a test case

Mapping
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="Like" table="`like`">
        <id name="id" type="integer" column="id">
            <generator strategy="SEQUENCE"/>
            <sequence-generator sequence-name="like_id_seq" allocation-size="1" initial-value="1"/>
        </id>

        <field name="value" column="value" type="string" />
    </entity>
</doctrine-mapping>
SQL
CREATE TABLE "like"
(
  id serial NOT NULL,
  "value" character varying,
  CONSTRAINT like_pkey PRIMARY KEY (id)
);
Class
class Like {

  private $id;
  public  $value;
}
Test case
$entity = new Like();
$entity->value = 'toto';

$doctrineEntityManager->persist($entity);
$doctrineEntityManager->flush();

$entity->value = 'tata';
$doctrineEntityManager->flush();
Comment by Benjamin Eberlei [ 30/Oct/10 ]

This issue partly depends on DBAL-57 (otherwise the testsuite keeps failing)

Comment by Benjamin Eberlei [ 30/Oct/10 ]

There is really no simple fix for this issue, your proposed one breaks joined table inheritance.

Comment by Benjamin Eberlei [ 30/Oct/10 ]

Found a way! fixed.





[DDC-732] Class Table Inheritance - wrong table order on insert with more than one level of inheritance Created: 06/Aug/10  Updated: 30/Oct/10  Resolved: 30/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA3
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Minor
Reporter: victor Velkov Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Attachments: File DDC732Test.php     File testDoc.sql    

 Description   

This is the error that i get when i try to create new entity Employee

$newEmployee = new Users_Entity_Model_Employee;
//here i set the data
.....

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

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`crm/Employees`, CONSTRAINT `employee_person` FOREIGN KEY (`contactID`) REFERENCES `Persons` (`contactID`) ON DELETE NO ACTION ON UPDATE NO ACTION)

/**
 *
 * @Entity
 * @InheritanceType("JOINED")
 * @Table(name="Contacts")
 * @DiscriminatorColumn(name="contactType", type="string")
 * @DiscriminatorMap({"PERSON" = "Users_Model_Entity_Person", "COMPANY" = "Users_Model_Entity_Company", "EMPLOYEE" = "Users_Model_Entity_Employee", "FIRM" = "Users_Model_Entity_Firm"})
 */
class Users_Model_Entity_Contacts 
{


	/**
	 *  @Id  @Column(name="contactID", type="integer")
	 *  @GeneratedValue(strategy="AUTO")
	 *
	 */
	protected $contactID;

	// ...

}

/**
 *
 * @Table(name="Persons")
 * @entity(repositoryClass="Users_Model_PersonRepo")


 */
class Users_Model_Entity_Person extends Users_Model_Entity_Contacts
{
 // ...
}




/**
 *
 * @Table(name="Employees")
 * @entity
 */
class Users_Model_Entity_Employee extends Users_Model_Entity_Person
{
	// .....
}


 Comments   
Comment by victor Velkov [ 06/Aug/10 ]

I managed to fix it but i am not sure that this is the wright solution. The problem is in the
Doctrine\ORM\Persisters\JoinedSubclassPersister in the function executeInserts()

if ( ! $this->_queuedInserts) {
            return;
        }

        if ($this->_class->isVersioned) {
            $versionedClass = $this->_getVersionedClassMetadata();
        }

        $postInsertIds = array();
        $idGen = $this->_class->idGenerator;
        $isPostInsertId = $idGen->isPostInsertGenerator();

        // Prepare statement for the root table
        $rootClass = $this->_class->name == $this->_class->rootEntityName ?
                $this->_class : $this->_em->getClassMetadata($this->_class->rootEntityName);
        $rootPersister = $this->_em->getUnitOfWork()->getEntityPersister($rootClass->name);
        $rootTableName = $rootClass->table['name'];
        $rootTableStmt = $this->_conn->prepare($rootPersister->_getInsertSQL());

        // Prepare statements for sub tables.
        $subTableStmts = array();
        if ($rootClass !== $this->_class) {
            $subTableStmts[$this->_class->table['name']] = $this->_conn->prepare($this->_getInsertSQL());
        }
        foreach ($this->_class->parentClasses as $parentClassName) {
            $parentClass = $this->_em->getClassMetadata($parentClassName);
            $parentTableName = $parentClass->table['name'];
            if ($parentClass !== $rootClass) {
                $parentPersister = $this->_em->getUnitOfWork()->getEntityPersister($parentClassName);
                $subTableStmts[$parentTableName] = $this->_conn->prepare($parentPersister->_getInsertSQL());
            }
        }


        // Execute all inserts. For each entity:
        // 1) Insert on root table
        // 2) Insert on sub tables
        foreach ($this->_queuedInserts as $entity) {
        	$insertData = $this->_prepareInsertData($entity);

            // Execute insert on root table
            $paramIndex = 1;
            foreach ($insertData[$rootTableName] as $columnName => $value) {
                $rootTableStmt->bindValue($paramIndex++, $value, $this->_columnTypes[$columnName]);
            }
            $rootTableStmt->execute();

            if ($isPostInsertId) {
                $id = $idGen->generate($this->_em, $entity);
                $postInsertIds[$id] = $entity;
            } else {
                $id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
            }
            
            /**
             * Here is the fix that i made
             */
           $subTableStmts = array_reverse($subTableStmts);
            /**
             * end 
             */
           
            // Execute inserts on subtables.
            // The order doesn't matter because all child tables link to the root table via FK.
            foreach ($subTableStmts as $tableName => $stmt) {
                $data = isset($insertData[$tableName]) ? $insertData[$tableName] : array();
                $paramIndex = 1;
                foreach ((array) $id as $idVal) {
                    $stmt->bindValue($paramIndex++, $idVal);
                }
                foreach ($data as $columnName => $value) {
                    $stmt->bindValue($paramIndex++, $value, $this->_columnTypes[$columnName]);
                }
                $stmt->execute();
            }
        }

        $rootTableStmt->closeCursor();
        foreach ($subTableStmts as $stmt) {
            $stmt->closeCursor();
        }

        if (isset($versionedClass)) {
            $this->_assignDefaultVersionValue($versionedClass, $entity, $id);
        }

        $this->_queuedInserts = array();

        return $postInsertIds;
    }

the order of the queue for insert was not correct.

Comment by Benjamin Eberlei [ 08/Aug/10 ]

thanks for the report, but posting large bunches of changed code isnt very helpful. You should post patches/diffs instead using "git diff" or "diff" against the original file.

I checked your patch and it cannot be right, you check the reverse inside the loop each time. Without a failing test-case i cant do anything here, i will look into it in more detail later.

Comment by victor Velkov [ 09/Aug/10 ]

Hi there sorry for that you are wright the reverse should be before the foreach. I will prepare the test- case and post it a bit later.

Comment by victor Velkov [ 09/Aug/10 ]

This is the database and the test case for inserting data and we have Class Table Inheritance. the problematic ones are

public function testInsertInheritedTwo(){ } 

and

public function testInsertInheritedThree(){ } 
Comment by victor Velkov [ 09/Aug/10 ]

Also i just updated to BETA3 and found one more problem in /Doctrine/DBAL/Statement.php in the 'function execute' on line 126. $this->_params = array(); This bit of code is braking the insert statements. Because it clears the currently bound parameters. Hope that is all the info you need if there is more information that is required please let me know.

Comment by Benjamin Eberlei [ 29/Aug/10 ]

What database and driver are you using? All three tests pass for me

Comment by Benjamin Eberlei [ 30/Aug/10 ]

can you please use the SQL generated from Doctrine Schema-Tool and try again if this issue occurs to you? You have generated your own SQL, this might be the issue.

Comment by victor Velkov [ 31/Aug/10 ]

Hi there,

I will try with the sql generated by Doctrine. But the problem I got was when I have more than 2 levels of the inheritance hierarchy. When try to make an insert trough the lowest level (in my example the DDC732Driver. Actually it was not working with the DDC732Employee entity as well) the order of inserting was not correct. First it went trough the correct entity (in my example the DDC732Contacts), but then instead of going through DDC732Person it try to go trough the last level (DDC732Driver or DDC732Employee depending on the example). And then the MySql said that it can not go trough. Also maybe the reason is that I am using InnoDB, but then it shouldn't really matter because I thought that the hierarchy inheritance is supposed to work with it. Actually I am almost 100% sure the problem is in the InnoDB could you please try with it. If it is still working for you i will reexamine my application and find the mistake.

Thanks in advance for the help and sorry. Now on second thought I should have explained all that in the beginning.

Comment by Benjamin Eberlei [ 15/Sep/10 ]

Doctrine2 only creates InnoDB tables. Are you using foreign keys in a different way?

Comment by Benjamin Eberlei [ 21/Sep/10 ]

Closed because we can't reproduce this. Schema of the user differs from the ORM SchemaTool and causes this issue.

Comment by victor Velkov [ 11/Oct/10 ]

Hi there i am reopening this ticket, because i found problem with the logic of creating inherited join tables from your create schema tool. I was expecting when we have more than one level of inherited tables the foreign key constrain to go to the parent and not to the root table. And because of that with the sql generated from your tool it was ok and it was not working with my sql. I would like to know are you going to fix that or it was intended to work that way from the beginning? Because logically for me and my colleagues if Employee extends Person then the foreign key constrain in Employee should go to Person and at the same time Person extends Contact then foreign key constrain in Person should go to Contact. And with your schema tool in that instance the foreign key constrain in Employee go to Contact which is wrong.

Comment by Benjamin Eberlei [ 30/Oct/10 ]

This is a documentation issue.

I have now documented the SQL schema requirements for inheritance scenarios.

Closing this issue.





[DDC-787] Camelcase tablename lost when creating models based on the database Created: 03/Sep/10  Updated: 30/Oct/10  Resolved: 30/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Van Hauwaert Bert Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Ubuntu
MySQL 5.1



 Description   

I have a table articleLocale and I created the model with the doctrine tool using the following command: # doctrine orm:convert-mapping --from-database annotation temp.

The model that was created was Articlelocale instead of ArticleLocale and the annotations were wrong.

<?php
/**
 * Articlelocale
 *
 * @Table(name="articlelocale")
 * @Entity
 */
class Articlelocale
{
//....
}

When trying to fetch some data, I get the following error: Message: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'doctrine.articlelocale' doesn't exist
If i change the annotation so that it reads articleLocale instead of articlelocale it works like it should be working.

<?php
/**
 * Articlelocale
 *
 * @Table(name="articleLocale")
 * @Entity
 */
class Articlelocale
{
//....
}

So there is a problem with camelCase table names.



 Comments   
Comment by Benjamin Eberlei [ 30/Oct/10 ]

Fixed





[DDC-711] Compatibility with Codeigniter 1.7.2 Created: 21/Jul/10  Updated: 30/Oct/10  Resolved: 30/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: 2.0-BETA2
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Trivial
Reporter: Deyan Yankov Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None
Environment:

Codeigniter 1.7.2 framework


Attachments: File Doctrine.php    

 Description   

Following the instructions in the website did not succeed with the configuration (Doctrine.php) file. Seems that there is a problem with the namespaces (the Doctrine folder is placed in \application\libraries folder of the Codeigniter structure) and the application cannot find its clases.



 Comments   
Comment by Benjamin Eberlei [ 21/Jul/10 ]

Can you come up with a solution? This recipe is not written by the Doctrine team, we don't have any skills in Code Igniter

Comment by Deyan Yankov [ 24/Jul/10 ]

Finally succeeded to start up Doctrine with Codeigniter. Attached is the configuration Library file for CI.

Comment by Benjamin Eberlei [ 30/Oct/10 ]

Added note to the manual.





[DDC-830] Missing prefix \ to switch to global space in Tools/EntityGenerator Created: 07/Oct/10  Updated: 30/Oct/10  Resolved: 30/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Martin Hasoň Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

If generated entity isn't in global namespace and extends class, name of extended class has to have prefix \ to switch to global namespace.

Fix: class Doctrine\ORM\Tools\EntityGenerator

Doctrine/ORM/Tools/EntityGenerator.php
private function _getClassToExtendName()
{
    $refl = new \ReflectionClass($this->_getClassToExtend());

    return '\\' . $refl->getName();
}


 Comments   
Comment by Benjamin Eberlei [ 30/Oct/10 ]

Fixed.





[DDC-767] Updating many-to-many relations Created: 25/Aug/10  Updated: 30/Oct/10  Resolved: 30/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA3
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Matti Niemelä Assignee: Benjamin Eberlei
Resolution: Duplicate Votes: 0
Labels: None

Attachments: File DDC767AmbisTest.php    
Issue Links:
Duplicate
is duplicated by DDC-839 Error when trying to update Persisten... Resolved

 Description   

I have an entity with a many-to-many relation.

When I delete all relations and then flush, add new relations and then flush, all inside one transaction, I get

Fatal error: Call to a member function update() on a non-object in Doctrine/ORM/UnitOfWork.php on line 312

        // Delete old categories
        foreach ($revision->getCategories() as $category) {
            $revision->removeCategory($category);
        }

        $this->entityManager->flush();

        // Add new
        foreach ($categories as $categoryId) {
            $category = $this->entityManager->find('Category', $categoryId);

            if ($category instanceof Category) {
                $revision->addCategory($category);
            }
        }

        $this->entityManager->flush();
Revision::getCategories()
    /**
     * @return ArrayCollection
     */
    public function getCategories()
    {
        return $this->categories;
    }
Revision::addCategory()
    /**
     * @param Category $category
     * @return Revision
     */
    public function addCategory(Category $category)
    {
        $this->categories->add($category);
        return $this;
    }
Revision::removeCategory()
    /**
     * @param Category $category
     * @return Revision
     */
    public function removeCategory(Category $category)
    {
        $this->categories->removeElement($category);
        return $this;
    }

If this is not a bug, I'd like to know which is the most efficient and elegant way to update many-to-many relationships.



 Comments   
Comment by Matti Niemelä [ 25/Aug/10 ]

When I add at least one relation between Revision and Category (directly into the db) everything works just as expected. I can add more and delete old. But as soon as all relations are deleted, this problem occurs.

Comment by Matti Niemelä [ 25/Aug/10 ]

I changed Revision::removeCategory() to Revision::removeCategories() which calls ->clear() on the ArrayColleciton. This didn't have any effect.

I also created a WHERE IN-query for the new categories to optimize the code a bit.

Comment by Matti Niemelä [ 02/Sep/10 ]

After updating to BETA4, the error message has changed:

Catchable fatal error: Argument 1 passed to Doctrine\ORM\UnitOfWork::getCollectionPersister() must be an array, null given, called in /usr/local/zend/share/pear/Doctrine/ORM/UnitOfWork.php on line 297 and defined in /usr/local/zend/share/pear/Doctrine/ORM/UnitOfWork.php on line 2131

    /**
     * @param Revision $revision
     * @param array $categories
     * @return Revision
     */
    private function updateRevisionCategories(Revision $revision, array $categories)
    {
        // Delete old categories
        $revision->removeCategories();
        $this->entityManager->flush();

        if ( ! empty($categories)) {
            // Query and add new ones
            $qb = $this->entityManager->createQueryBuilder();

            $qb->select('category')
               ->from('Category', 'category')
               ->where($qb->expr()->in('category.id', $categories));

            $query = $this->entityManager->createQuery($qb);

            foreach ($query->getResult() as $category) {
                $revision->addCategory($category);
            }

            $this->entityManager->flush();
        }

        return $revision;
    }
Comment by Benjamin Eberlei [ 15/Sep/10 ]

I committed a testcase with your scenario that shows it works. It seems there is something wrong with your entity code, can you show more? Or try to make tests/Doctrine/Tests/ORM/Functional/Ticket/DDC767Test.php

http://github.com/doctrine/doctrine2/commit/810a129a3273a3826ecedb4b744a55e33a54a3ff

Comment by Matti Niemelä [ 02/Oct/10 ]

Yeah I just now noticed you were using em->clear() there.

I got all things working after I started using:

entity->removeCategories()

em->flush()
em->clear()

entity = em->merge(entity)

Is ther something inherintly wrong here? I wouldn't want to reload the entity because 1) I would neet to hit the db and 2) all the relations might not come along which are already loaded for it when first obtained before.

Comment by Matti Niemelä [ 02/Oct/10 ]

All was good up until I realized that using the em->merge(entity) breaks the object reference.

I do things much like:

$entity = loadById($id)
beginTransaction()
try {
service->doStuff($entity, $data) 
otherService->doOtherStuff($entity, $data)
commit()
} catch ...

Now, when I have to merge the entity inside the doStuff() service method, the managed object is not the same object doOtherStuff gets.

So, what I've gathered is that a PersistentCollection cannot be cleared, flushed, re-populated and then flushed again without things breaking catastrophically (see my 3rd comment for the error I get).

I'd like to see your test case work without clearing the entity manager at any point.

Or at least I'd love to hear the reasoning behind the clearing process if it truly is required.

Comment by Matti Niemelä [ 02/Oct/10 ]

Here is a test which fails with the following error and is 1:1 to my case:

Argument 1 passed to Doctrine\ORM\UnitOfWork::getCollectionPersister() must be an array, null given, called in doctrine2/lib/Doctrine/ORM/UnitOfWork.php on line 302 and defined

Full trace in my app:

exception 'ErrorException' with message 'Argument 1 passed to Doctrine\ORM\UnitOfWork::getCollectionPersister() must be an array, null given, called in /usr/local/zend/share/pear/Doctrine/ORM/UnitOfWork.php on line 302 and defined' in /usr/local/zend/share/pear/Doctrine/ORM/UnitOfWork.php:2131
Stack trace:
#0 /usr/local/zend/share/pear/Doctrine/ORM/UnitOfWork.php(2131): ***_ErrorHandler::handleError(4096, 'Argument 1 pass...', '/usr/local/zend...', 2131, Array)
#1 /usr/local/zend/share/pear/Doctrine/ORM/UnitOfWork.php(302): Doctrine\ORM\UnitOfWork->getCollectionPersister(NULL)
#2 /usr/local/zend/share/pear/Doctrine/ORM/EntityManager.php(320): Doctrine\ORM\UnitOfWork->commit()
#3 ***/ImageGroupService.php(182): Doctrine\ORM\EntityManager->flush()
#4 ***EntryUsercpController.php(104): ***ImageGroupService->setImageGroupImages(Object(***ImageGroup), Array, NULL)
#5 library/ZendFramework-1.10.8/library/Zend/Controller/Action.php(513): ***EntryUsercpController->imagesAction()
#6 library/ZendFramework-1.10.8/library/Zend/Controller/Dispatcher/Standard.php(295): Zend_Controller_Action->dispatch('imagesAction')
#7 library/ZendFramework-1.10.8/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#8 library/ZendFramework-1.10.8/library/Zend/Application/Bootstrap/Bootstrap.php(97): Zend_Controller_Front->dispatch()
#9 library/ZendFramework-1.10.8/library/Zend/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
#10 dev.sotavasara.net/published/index.php(26): Zend_Application->run()
#11 {main} 
Comment by Matti Niemelä [ 02/Oct/10 ]

Please review attached test case.

Comment by Benjamin Eberlei [ 30/Oct/10 ]

Duplicate of DDC-839, and fixed.





[DDC-839] Error when trying to update PersistentCollection Created: 15/Oct/10  Updated: 30/Oct/10  Resolved: 29/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: victor Velkov Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Duplicate
duplicates DDC-767 Updating many-to-many relations Resolved

 Description   

This is the error that i get :
"Argument 1 passed to Doctrine\ORM\UnitOfWork::getCollectionPersister() must be an array, null given, called in /home/vis/projects/CRM/trunk/library/Doctrine/ORM/UnitOfWork.php on line 302 and defined at /home/vis/projects/CRM/trunk/library/Doctrine/ORM/UnitOfWork.php:2149"

This happens when i try to update Entity that have PersistentCollection but when i was creating the entity did not create entities to be attached to it by the PersistentCollection. Later on i called it and and used :

$collectionEntity = $em->getRepository('CollectionEntityName')->findOneBy($data);
$entity                   = $em->getRepository('EntityName')->findOneBy($entityData);
$entity->getCollection()->add($collectionEntity);
$em->presist();
$em->flush();


 Comments   
Comment by victor Velkov [ 15/Oct/10 ]

After some investigating i did find a solution that seems to work.
In Doctrine\ORM\UnitOfWork;
in the function computeChangeSet()

from line 482

 // Look for changes in associations of the entity
        foreach ($class->associationMappings as $field => $assoc) {
            $val = $class->reflFields[$field]->getValue($entity);
            if ($val !== null) {

           	/**
            	 * Fix done by Victor on 15.10.2010
            	 */
            	if ($val instanceof PersistentCollection) {
            		$val->setOwner($entity, $assoc);
            	}
            	/**
            	 * End Fix
            	 */

                $this->computeAssociationChanges($assoc, $val);

            }
        }

That way i make sure that the owner for the PersistentCollection is set for sure and when it is called in the commit function it does not give errors.

Hope that this solution will work for you.

Comment by Jordi Boggiano [ 28/Oct/10 ]

I hit the same issue, if a many-to-many's collection is empty (either at the firstr creation or if you clear()'d it later on), and then you add() something to it and try to flush, it does not know its parent.

Victor's fix has also been verified here. Not sure if it's the best way, but it's working. Please fix this asap because it's essentially preventing relations to be used for me. I had to resort to a ugly hack for the time being to always have one item in the association that is hidden..

Comment by Benjamin Eberlei [ 29/Oct/10 ]

Fixed





[DDC-833] Internal Collection of a PersistentCollection is an Entity Created: 07/Oct/10  Updated: 11/Oct/10  Resolved: 11/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-RC1
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Jeff Reiffers Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:
  1. Windows Vista
  2. Apache 2.2.14
  3. MySQL 5.1.41
  4. PHP 5.3.1
  5. Perl 5.10.1
  6. PHPUnit 3.5.0


 Description   

The creation of an Associated Collection of a Proxy Class is broken by this line:

$reflField->getValue($entity) ?: new ArrayCollection

$entity is a Proxy Class and the property is the field users. The function ReflectionProperty::getValue() will return an Entity User. This results that the internal collection of the PersistenCollection is an Entity. This results in:

Fatal error: Call to undefined method Entity\User::clear() in \library\Doctrine\ORM\PersistentCollection.php on line 206

This is my Entity Configuration

class Organization {
    /**
     * @OneToMany(targetEntity="User", mappedBy="organization", cascade={"persist", "remove"})
     */
    private $users;    

    public function __constructor() {
      $this->users = new ArrayCollection();
   }
}

class User {
    /**
     * @ManyToOne(targetEntity="Organization", inversedBy="users")
     * @JoinColumn(name="organization_id", referencedColumnName="id")
     */	
 	private $organization; 	
}


 Comments   
Comment by Benjamin Eberlei [ 11/Oct/10 ]

Fixed formatting

Comment by Benjamin Eberlei [ 11/Oct/10 ]

I don't understand why this $reflField->getValue() returns a user entity. It should only return either NULL or a collection.

Comment by Benjamin Eberlei [ 11/Oct/10 ]

fixed aswell as another nasty bug.





[DDC-834] EntityManager::getReference may return proxy for parent class when using class table inheritance Created: 08/Oct/10  Updated: 11/Oct/10  Resolved: 11/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Patrick Schwisow Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

When using class table inheritance, it is possible for a parent class proxy to get saved into the identifier map.

Classes:

/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"employee" = "Employee", "customer" = "Customer"})
 */
class Person
{
   ...
}

/** @Entity */
class Employee extends Person
{
    ...
    public function getEmployeeNumber()
    ...
}

The following will fail:

$person = $entityManager->getReference('Person', 1);  // the identity map contains a PersonProxy with id 1

...

$employee = $entityManger->getReference('Employee', 1);  // $employee is set to the PersonProxy object in the identity map

...

$employee->getEmployeeNumber();  // error, PersonProxy object does not have a getEmployeeNumber method


 Comments   
Comment by Benjamin Eberlei [ 11/Oct/10 ]

Fixed this issue. Classes that have further entity subclasses CANNOT be loaded by reference. This is a technical requirement. Go live with it inheritance users

Also updated the docs:

There is a general performance consideration with Single and Class Table Inheritance: If you use a STI/CTI entity as
a many-to-one or one-to-one entity you should never use one of the classes at the upper levels of the
inheritance hierachy as "targetEntity", only those that have no subclasses. Otherwise Doctrine *CANNOT*
create proxy instances of this entity and will *ALWAYS* load the entity eagerly.




[DDC-831] Return value of getAssociationMapping in class Doctrine\ORM\Mapping\ClassMetadataInfo Created: 07/Oct/10  Updated: 10/Oct/10  Resolved: 10/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: victor Velkov Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None


 Description   

The problem is in the comment of function return value is Doctrine\ORM\Mapping\AssociationMapping.
My code expected to work with object of this type and normal situation is Fatal error: Call to a member function isOneToOne() on a non-object in /home/vis/projects/crm/trunk/library/Viscomp/Doctrine/Repository.php on line 371.

In my mind I suppose is normal to return object of Doctrine\ORM\Mapping\AssociationMapping, because in comment return value have this type.

I will be grateful if have fast answer because this is blocking issue for my project.

 /**
     * Gets the mapping of an association.
     *
     * @param string $fieldName  The field name that represents the association in
     *                           the object model.
     * @return Doctrine\ORM\Mapping\AssociationMapping  The mapping.
     */
    public function getAssociationMapping($fieldName)
    {
        if ( ! isset($this->associationMappings[$fieldName])) {
            throw MappingException::mappingNotFound($this->name, $fieldName);
        }
        return $this->associationMappings[$fieldName];
    }


 Comments   
Comment by Benjamin Eberlei [ 07/Oct/10 ]

That is out of date, Association Mappings are now arrays. See the public $associationMappings definition how this array is structured.

Comment by victor Velkov [ 08/Oct/10 ]

Could you please change the comment of return value of this method.

Comment by Benjamin Eberlei [ 10/Oct/10 ]

fixed





[DDC-673] yaml metadata allows integer(X) types but ignores the X Created: 07/Jul/10  Updated: 06/Oct/10  Resolved: 06/Oct/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA2
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Minor
Reporter: Nathanael Noblet Assignee: Christian Heinrich
Resolution: Fixed Votes: 0
Labels: None
Environment:

Fedora 13, php 5.3.2, apache mysql etc.


Attachments: File Account.dcm.yml    

 Description   

When using the yaml mapping driver, it is possible (and in fact used by the yaml exporter) to have type: integer(X). doctrine never complains, however it always creates mysql int(11) fields regardless of the X. It should either cause an error at some point (like it does in the annotation driver according to romanb) or observe the X when creating the integer size.



 Comments   
Comment by Christian Heinrich [ 17/Jul/10 ]

I think we should throw an error in that case and change the yaml exporter to observe this rule.

Roman, would that be okay? If so, I'll try to fix it before the next beta.

Comment by Roman S. Borschel [ 28/Jul/10 ]

Yes, I guess that would be fine.

Comment by Benjamin Eberlei [ 06/Oct/10 ]

Fixed





[DDC-798] Clarify param term in MEMBER OF example in DQL docs Created: 10/Sep/10  Updated: 30/Sep/10  Resolved: 30/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Improvement Priority: Minor
Reporter: Marc Hodgins Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

Current code example reads:

$query = $em->createQuery('SELECT u.id FROM CmsUser u WHERE :param MEMBER OF u.groups');
$ids = $query->getResult();

Maybe it's just me, but it was not immediately apparent that :param is expected to be an identifier value from the CmsGroups entity (group ID number). It may improve the example to rename :param to :groupId or add $query->setParameter(':param', $groupId);



 Comments   
Comment by Roman S. Borschel [ 10/Sep/10 ]

Its supposed to be an object, not an id, although an id might work too, I dont know.

Comment by Marc Hodgins [ 10/Sep/10 ]

Ok. Well, a clarification of whatever is permitted there would improve the docs. An id does seem to work.

Comment by Benjamin Eberlei [ 30/Sep/10 ]

Fixed





[DDC-797] WHERE EXISTS example code doesn't make sense in docs Created: 10/Sep/10  Updated: 30/Sep/10  Resolved: 30/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Improvement Priority: Major
Reporter: Marc Hodgins Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None


 Description   

Example for "WHERE EXISTS" in DQL section of docs currently reads:

$query = $em->createQuery('SELECT u.id FROM CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM CmsPhonenumber p WHERE p.phonenumber = u.id)');

But, p.phonenumber = u.id doesn't make sense - you're comparing the PK of a CmsPhoneNumber to a PK of a CmsUser. I think it is supposed to be p.user = u.id :

$query = $em->createQuery('SELECT u.id FROM CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM CmsPhonenumber p WHERE p.user = u.id)');

Also consider updating the test at Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php line 466 to match.



 Comments   
Comment by Benjamin Eberlei [ 30/Sep/10 ]

Fixed





[DDC-822] Query with detached Entity as parameter fails to execute Created: 30/Sep/10  Updated: 30/Sep/10  Resolved: 30/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Nico Kaiser Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File ddc-822.patch    

 Description   

When dealing with detached entities, e.g. with the QueryCache, you cannot use these entities as parameters for other Query.

Example:

Unable to find source-code formatter for language: php. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
$em->detach($user);
$query = $em->createQuery('SELECT a FROM Address a WHERE a.User = ?1');
$query->setParameter(1, $user); // $user is detached

As $user is detached, the EntityManager does not have its identifier, so Query::_doExecute fails. (There is a "//TODO: Check that $value is MANAGED?" line near the failing line).



 Comments   
Comment by Nico Kaiser [ 30/Sep/10 ]

This patch should fix Doctrine\ORM\Query to work with detached Entities.

Comment by Benjamin Eberlei [ 30/Sep/10 ]

Did some changes to the patch, but overally its now committed!





[DDC-793] CLI doctrine.php tool should not hard code require_once paths -- leave the include path setup to cli-config.php Created: 07/Sep/10  Updated: 30/Sep/10  Resolved: 30/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Marc Hodgins Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

The current CLI tool doctrine.php makes assumptions about lib/vendor paths. Consider refactoring to allow cli-config.php to contain any include path/autoloader setup and remove hard coded paths from doctrine.php



 Comments   
Comment by Benjamin Eberlei [ 30/Sep/10 ]

Denied! That is really the PEAR binary code, nothing used in another context.

I refactored the large bunch of code to Doctrine\ORM\Tools\Console\ConsoleRunner::main() and ::addCommands().





[DDC-784] Add Windows CLI command and remove doctrine.php Created: 01/Sep/10  Updated: 30/Sep/10  Resolved: 30/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

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


 Description   

Add a Windows CLI .bat and remove the annoying doctrine.php that duplicates doctrine binary.



 Comments   
Comment by Benjamin Arthur Lupton [ 13/Sep/10 ]

What about OSX users?

Comment by Benjamin Eberlei [ 13/Sep/10 ]

What about them? Don't they have a shell that listens to #!/bin/sh ?

Comment by Benjamin Eberlei [ 30/Sep/10 ]

Implemented





[DDC-820] Nullable associations combined with a column definition generates a notice Created: 29/Sep/10  Updated: 29/Sep/10  Resolved: 29/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Harold Asbridge Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None
Environment:

Ubuntu 9.10, PHP 5.3.3, MySQL 5.0.83


Attachments: GZip Archive doctrine-test.tar.gz    

 Description   

When an entity has an optional association on a given field and also a column definition on that field, loading that entity generates a notice in UnitOfWork.php on line 1884. Other than the notice, the code works fine. This is the line:

$joinColumnValue = $data[$srcColumn];

Suggested fix:

$joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null;

I have attached a test case which reproduces the issue.



 Comments   
Comment by Benjamin Eberlei [ 29/Sep/10 ]

This is already fixed in master, will be in RC1.





[DDC-815] Identifier quoting does not work with unique columns in PostgreSQL Created: 24/Sep/10  Updated: 27/Sep/10  Resolved: 27/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Tomasz Jędrzejewski Assignee: Roman S. Borschel
Resolution: Won't Fix Votes: 1
Labels: None
Environment:

PostgreSQL 8.4



 Description   

It seems that Doctrine ORM tries to generate invalid unique index names, when the table name is quoted and one of the columns uses the "unique" annotation:

/**
 * Users\User
 *
 * @Table(name="`User`")
 * @Entity
 */
class User
{
	/**
	 * @var string $login
	 *
	 * @Column(name="login", type="string", length=40, unique=true)
	 */
	protected $login;

Expected result:

The table gets created.

Actual result:

Creating database schema...
Doctrine\DBAL\Schema\SchemaException
Invalid index-name "User"_login_uniq given, has to be [a-zA-Z0-9_]
/.../Doctrine/DBAL/Schema/SchemaException.php
Line 33
Trace:
        0. Doctrine\DBAL\Schema\SchemaException::indexNameInvalid on line 214
        1. Doctrine\DBAL\Schema\Table::_createIndex on line 176
        2. Doctrine\DBAL\Schema\Table::addUniqueIndex on line 341
        3. Doctrine\ORM\Tools\SchemaTool::_gatherColumn on line 273
        4. Doctrine\ORM\Tools\SchemaTool::_gatherColumns on line 193
        5. Doctrine\ORM\Tools\SchemaTool::getSchemaFromMetadata on line 93
        6. Doctrine\ORM\Tools\SchemaTool::getCreateSchemaSql on line 76
        7. Doctrine\ORM\Tools\SchemaTool::createSchema on line 73
        8. Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand::executeSchemaCommand on line 59
        9. Doctrine\ORM\Tools\Console\Command\SchemaTool\AbstractCommand::execute on line 159
        10. Symfony\Component\Console\Command\Command::run on line 205
        11. Symfony\Component\Console\Application::doRun on line 117
        12. Symfony\Component\Console\Application::run on line 72

I don't know whether the problem is caused by ORM which forgets that the table names can be quoted, or by DBAL for the same reason. Anyway, I think this should be fixed. I agree with your argumentation that identifier quoting can be wrong, but you should also remember that Doctrine can be used in cooperation with other ORM libraries or with legacy databases. I am in this particular situation: the database is shared by two different systems written in two different languages and using two different ORM libraries, and this is a big limitation for me.



 Comments   
Comment by Benjamin Eberlei [ 24/Sep/10 ]

1. Why do you need SchemaTool if you have a legacy database?

2. You can use @Table(uniqueConstraints=...) to specify the index name, this circumvents your problem http://www.doctrine-project.org/projects/orm/2.0/docs/reference/annotations-reference/en#ann_table

Comment by Benjamin Eberlei [ 27/Sep/10 ]

This issue has a simple workaround and no possible sane solution undoing the quoting.





[DDC-525] STI Fields null vs not null behaviour Created: 16/Apr/10  Updated: 27/Sep/10  Resolved: 27/Sep/10

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

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


 Description   

What is the expected behaviour for fields on STI sub-classes?

  • Should they always be DEFAULT NULL?
  • Should the EntityPersister always write a default value to them?

A user reported on IRC that he had issues with Sqlite inserting null values (failing) vs Mysql which inserted empty strings.



 Comments   
Comment by Benjamin Eberlei [ 16/Apr/10 ]

<mluiten> beberlei; final note before i move to other issues: I found that MySQL puts empty strings in columns that are not specified in the column list of the query, vs sqlite that puts nulls into non-specified columns. That explains a lot of it..

Comment by Menno Luiten [ 16/Apr/10 ]

Said user reporting in

Found this extremely annoying mostly due to inconsistent behavior between different drivers. I just found that MySQL inserts empty strings ('') into columns not specified in the INSERT query, while SQLite inserts NULLs. I'd say SQLite is technically correct..

E.g. a superclass Collector (id, name) which has a subclass SpecialCollector, with the column 'subdomain' added (nullable=false).

CREATE TABLE Collector (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(255) NOT NULL, subdomain VARCHAR(255) NOT NULL)
// Mysql
INSERT INTO Collector (id, name) VALUES (1, 'foo'); // Works fine... subdomain value in new row = '' (empty string)
INSERT INTO Collector(id, name, subdomain) VALUES (1, 'foo', NULL); // Error, subdomain may not be NULL
// SQLite
INSERT INTO Collector (id, name) VALUES (1, 'foo'); // Error, subdomain may not be NULL
INSERT INTO Collector(id, name, subdomain) VALUES (1, 'foo', NULL); // Error, subdomain may not be NULL

When creating a subclass without the subdomain field, Doctrine creates an insert query without subdomain and thus works fine. SQLite however, gives an error.

Possible solutions would be to include every column of subclasses to the query and hard-set to empty string, or to imply NOT NULL on all columns of subclasses during table creation, and check for NULL in the DBAL instead. But I'll let the big boys figure that out

Comment by Roman S. Borschel [ 16/Apr/10 ]

Columns mapped by child classes in single table inheritance must be nullable.

The behavior of mysql looks weird to me, too.

Comment by Roman S. Borschel [ 26/Apr/10 ]

So do we have an issue here, assuming columns mapped by child classes in STI must be nullable? If yes what is the problem?

Comment by Benjamin Eberlei [ 27/Sep/10 ]

The problem is that currently you had to do nullable=true on all the fields in chield entities of STI.

Now SchemaTool doe this automatically.





[DDC-533] Cache keys are not limited to word characters Created: 21/Apr/10  Updated: 27/Sep/10  Resolved: 27/Sep/10

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

Type: Bug Priority: Major
Reporter: Nico Kaiser Assignee: Benjamin Eberlei
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

I'm currently working on some glue classes to integrate Doctrine 2 into an existing Zend Framework project.
To be able to re-use our caching classes (which use Zend_Cache), I wrote a \Doctrine\Common\Cache\AbstractCache implementation for Zend_Cache:

http://pastie.org/926891

However Zend_Cache only allows "a-zA-Z0-9_" for cache keys, while Doctrine seems to allow anything, and Doctrine ORM seems to use at lease "\" and "$" for metadata storage ("Entity\Article\Category$CLASSMETADATA").

What do you think is the most elegant way to solve this?

  • Should Doctrine also limit the cache key characters?
  • How could _encodeId and _decodeId be implemented?


 Comments   
Comment by Nico Kaiser [ 21/Apr/10 ]

Currently the cached results and queries are saved with an md5 key anyway, so this works out of the box.

The only ones that make problems are metadata cache, which stores "Entity\Article\Category$CLASSMETADATA". As the Doctrine caching layer can be used separate from the other components, it may be a good idea to still allow arbitrary keys and mapping them internally.

Comment by Nico Kaiser [ 21/Apr/10 ]

Don't know the reason for Zend_Cache only supporting "\w+". When using file cache for Zend, it stores the keys in the filenames instead of hashing them, so the allowed characters have to be limited in order to be able to support a wide range of backends (files, database, etc.)...

Comment by Nico Kaiser [ 21/Apr/10 ]

Even base64 does not work, as it has the "+" and "/" characters (and the "=" padding character).

By stripping the = (PHP's base64 implementations does not seem to need it) and escaping + and / with the _ (not in base64), it works:

http://pastie.org/927679

But this is a really dirty hack... (md5'ing does not help, as getIds() requires the cache key encoding to be bidirectional)

Comment by Roman S. Borschel [ 30/Aug/10 ]

If the cache keys are going to be changed this needs to happen for RC1, therefore rescheduling.

Comment by Benjamin Eberlei [ 16/Sep/10 ]

I don't think this is necessary, why would you want to nest a Zend Cache adapter inside a Doctrine Cache instead of just using that cache?

Comment by Nico Kaiser [ 16/Sep/10 ]

When you integrate Doctrine 2 into an existing project that uses, manages and provides Zend_Cache instances? In our case, we have centralized factories that deliver the Zend_Cache instances (depending from configuration, environment, etc.), so we don't want to add additional cache configuration logic for Doctrine.

Comment by Guilherme Blanco [ 23/Sep/10 ]

This is not a problem that we need to fix. It's a problem with Zend Framework.
We cannot do anything here. I'd mark it as "Invalid", since it's up to Zend Framework fix their limitation.

If possible I'd make the ClassMetadata hash generator as a configuration extension.
I cannot imagine anything more than this.

Comment by Benjamin Eberlei [ 24/Sep/10 ]

@Guilherme Zend Cahce restricts the keys because of the filesystem cache. It needs proper chars i guess.

@Nico: Why not use str_replace and replace the chars into words?

$key = str_replace(array('\\', '$'), array('__NS__', '__USD__'), $key);

If you use a cache other than ArrayCache for the Annotations you need to translate that chars also, they contain other stuff that is not filesystem compliant.

Comment by Nico Kaiser [ 24/Sep/10 ]

This is the way I do it currently. Not the most elegant way, but it seems to work...
Which other characters are used for Annotations?

Comment by Benjamin Eberlei [ 27/Sep/10 ]

$, # and :: (dollar, hash and double colon).

Comment by Benjamin Eberlei [ 27/Sep/10 ]

Closed, this won't be changed and there is a simple workaround to be applied in the wrapping driver replacing \, ::, $, #





[DDC-819] Attempting to search a recursive relationship by null results in an error... Created: 26/Sep/10  Updated: 27/Sep/10  Resolved: 27/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Alexander Trauzzi Assignee: Benjamin Eberlei
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

Ubuntu Linux, MySQL


Issue Links:
Duplicate
duplicates DDC-817 Repository Query by associated ID Resolved

 Description   

I have an entity which has a many to one relationship pointing to itself. This is ultimately set to map parent/child relationships.

Consider the following snippet:

// Start out assuming we are searching for "Pages" with no parent specified (root level).
$parentId = null;

// Check to see if we're fetching pages that are a child of a parent.
if(array_key_exists("parent_id", $_GET))

{ $parentId = $_GET['parent_id']; }

$pages = $this->entityManager->getRepository("MyNamespace\Models\Page")->findByParent($parentId);

When this code is run, PHP tells me:

PHP Fatal error: Uncaught exception 'Doctrine\\ORM
ORMException' with message 'You need to pass a parameter to 'findByParent''

At which point, it's obvious that it's expecting a parameter an receiving none. The problem here however is that I have no way of matching for null. Is there some kind of surrogate null php-class that can be created to represent a model-null?



 Comments   
Comment by Benjamin Eberlei [ 27/Sep/10 ]

This is a duplicate of DDC-817, querying by associated ids inside the repositories is currently not possible. You have to use DQL for it.

Comment by Alexander Trauzzi [ 27/Sep/10 ]

While that is relevant to this issue, the problem I outlined here isn't just to do with being able to query an association by ID. It's about how I want to match for entities that have null specified.

This problem would arise with any regular field. Note: the error that I'm getting "you need to pass a parameter to findByParent". That's a PHP error, not Doctrine2. Which means the method isn't even getting a chance to run.

I understand that currently it won't work once it does run, but there has to be some way to test for null...

Comment by Benjamin Eberlei [ 27/Sep/10 ]

you are right, there is another bug

Comment by Benjamin Eberlei [ 27/Sep/10 ]

Fixed!

Comment by Alexander Trauzzi [ 27/Sep/10 ]

Unrelated to the fix, split this off if necessary: Looking at the other issue you linked in, it appears as though the column that stores the actual foreign key will be forced into becoming a primary key. Which is not really optimal. Is there any way to do this without creating another primary key on the entity?

Comment by Benjamin Eberlei [ 27/Sep/10 ]

err i just realized that this fix is bullshit.

the query turns into WHERE foo = ''.

There is no conversion into IS NULL. This case can only be solved by DQL.

Comment by Benjamin Eberlei [ 27/Sep/10 ]

I reverted this patch in the fix for DDC-817

Comment by Benjamin Eberlei [ 27/Sep/10 ]

@Alexander: I don't get your foreign key to primary key force question, there is no such requirement.





[DDC-817] Repository Query by associated ID Created: 25/Sep/10  Updated: 27/Sep/10  Resolved: 27/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: New Feature Priority: Major
Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Duplicate
is duplicated by DDC-819 Attempting to search a recursive rela... Resolved

 Description   

The DDC-117 already has an implementation for this. We need a way to use the EntityRepository to query by foreign key or the related object instance.

This should be in 2.0



 Comments   
Comment by Benjamin Eberlei [ 27/Sep/10 ]

Implemented, you can now do repository queries like:

$post = $em->getRepository('Post')->findByCategory($categoryId);

This does however NOT allow something like the following:

$post = $em->getRepository('Post')->findByCategory($category);

with $category being an instance of the entity. Only lookups per key are allowed.

It also obviously only works on the owning side of an association.





[DDC-653] Convert annotation mapping to xml having troubles with discriminator map Created: 24/Jun/10  Updated: 25/Sep/10  Resolved: 25/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA2
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Frantisek Troster Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,

I wanted to convert Company model from unit test folder in Doctrine 2
project but I get following error:

> doctrine orm:convert-mapping xml /var/www/doctrine-xml/

Entity class 'CompanyPerson' used in the discriminator map of class
'Doctrine\Tests\Models\Company\CompanyPerson' does not exist.

I'm able to convert all other models without any errors and didn't
make any changes to the test models from the current Git version. I
checked the discriminator definitions against documentation and it
seems ok. I have updated Doctrine 2 with all related packages today
form Git. Could you please let me know what am I doing wrong?

Thank you



 Comments   
Comment by Benjamin Eberlei [ 15/Aug/10 ]

works for me, can you explain where you get the error described and also paste the stack trace?

Comment by Roman S. Borschel [ 30/Aug/10 ]

If we don't get any more feedback and can not reproduce this issue it will be unscheduled from BETA4 since the release is close.

Comment by Frantisek Troster [ 30/Aug/10 ]

Hi,

sorry I was away for a few weeks. Here is the stack trace:

                                                                                                                                 
  [Doctrine\ORM\Mapping\MappingException]                                                                                            
  Entity class 'CompanyPerson' used in the discriminator map of class 'Doctrine\Tests\Models\Company\CompanyPerson' does not exist.  
                                                                                                                                     
orm:convert-mapping [--filter="..."] [--from-database] [--extend[="..."]] [--num-spaces[="..."]] [-h|--help] [-q|--quiet] [-v|--verbose] [-V|--version] [-c|--color] [-n|--no-interaction] command to-type dest-path


Exception trace:
 () at /var/www/doctrine2/lib/Doctrine/ORM/Mapping/MappingException.php:187
 Doctrine\ORM\Mapping\MappingException::invalidClassInDiscriminatorMap() at /var/www/doctrine2/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:1180
 Doctrine\ORM\Mapping\ClassMetadataInfo->setDiscriminatorMap() at /var/www/doctrine2/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php:187
 Doctrine\ORM\Mapping\Driver\AnnotationDriver->loadMetadataForClass() at /var/www/doctrine2/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:256
 Doctrine\ORM\Mapping\ClassMetadataFactory->_loadMetadata() at /var/www/doctrine2/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:155
 Doctrine\ORM\Mapping\ClassMetadataFactory->getMetadataFor() at /var/www/doctrine2/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:102
 Doctrine\ORM\Mapping\ClassMetadataFactory->getAllMetadata() at /var/www/doctrine2/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php:100
 Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand->execute() at /var/www/doctrine2/lib/vendor/Symfony/Components/Console/Command/Command.php:159
 Symfony\Components\Console\Command\Command->run() at /var/www/doctrine2/lib/vendor/Symfony/Components/Console/Application.php:205
 Symfony\Components\Console\Application->doRun() at /var/www/doctrine2/lib/vendor/Symfony/Components/Console/Application.php:117
 Symfony\Components\Console\Application->run() at /var/www/doctrine2/doctrine.php:61

I'm using version:

php doctrine.php -V
Doctrine Command Line Interface version 2.0.0BETA4-DEV

Please let me know if you need more information. Maybe it's just me having wrong configuration.

Comment by Jonathan H. Wage [ 31/Aug/10 ]

Can you provide the entity classes you are getting the errors with?

Comment by Benjamin Eberlei [ 01/Sep/10 ]

Its the Doctrine\Tests\Models\Company model-set in our suite.

Comment by Benjamin Eberlei [ 25/Sep/10 ]

Fixed the underlying issue, but this still won't work since mapping conversion is not currently possible with inheritance.





[DDC-816] orm:schema-tool:create --dump-sql is preceded by invalid sql statements Created: 24/Sep/10  Updated: 25/Sep/10  Resolved: 25/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Minor
Reporter: Steffen Vogel Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Ubuntu 10.4, Apache 2.2, PHP 5.3.3



 Description   

I used to create the schema dump for non-doctrine users with:

bin/doctrine orm:schema-tool:create --dump-sql > sql/mysql.sql

The output is now preceded by the following warning:

ATTENTION: This operation should not be executed in an production enviroment.

I would suggest to direct this warning to stderr so we can easily create our dumps



 Comments   
Comment by Benjamin Eberlei [ 25/Sep/10 ]

Fixed





[DDC-514] Default for discriminator column Created: 12/Apr/10  Updated: 23/Sep/10  Resolved: 23/Sep/10

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

Type: Improvement Priority: Minor
Reporter: Roman S. Borschel Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

The discriminator column should default to

@DiscriminatorColumn(name="dtype", type="string")

whenever the inheritance type is not NONE and there is no explicit @DiscriminatorColumn specified.



 Comments   
Comment by Benjamin Eberlei [ 23/Sep/10 ]

Implemented





[DDC-630] Column aliases are not properly quoted Created: 09/Jun/10  Updated: 23/Sep/10  Resolved: 23/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA1
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Minor
Reporter: Andriy Savchenko Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

ubuntu x64, php 5.3.1, Mysql 5.0.31, but can be reproduced in any environment



 Description   

Sandbox

xml

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <entity name="Entities\User" table="users">
        <id name="id" type="integer">
            <generator strategy="AUTO"/>
        </id>
        <field name="name" type="string" length="50" column="`test-name`"/>
    </entity>
</doctrine-mapping>

code

$user = new User;
$user->setName("tester");
$em->persist($user);
$em->flush();
$user2 = $em->getRepository('Entities\User')->find(1);

Expectected to get valid user entity
Got

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-name1, t0.id AS id2 FROM users t0 WHERE t0.id = '1'' at line 1' in /Doctrine/DBAL/Connection.php:566
Stack trace:
#0 /lib/Doctrine/DBAL/Connection.php(566): PDOStatement->execute(Array)
#1 /lib/Doctrine/ORM/Persisters/BasicEntityPersister.php(493): Doctrine\DBAL\Connection->executeQuery('SELECT t0.`test...', Array)
#2 /lib/Doctrine/ORM/EntityRepository.php(106): Doctrine\ORM\Persisters\BasicEntityPersister->load(Array)
#3 /index.php(61): Doctrine\ORM\EntityRepository->find(1)

Loks like the problem is in the BasicEntityPersister::_getSelectColumnSQL



 Comments   
Comment by Roman S. Borschel [ 08/Aug/10 ]

You mention BETA1 as the affected version. Can you confirm that this issue still exists in the BETA3 release and/or the master repository?

Comment by Benjamin Eberlei [ 15/Aug/10 ]

Are dashes even allowed in column names? I dont think so.

Comment by Christian Heinrich [ 19/Aug/10 ]

I don't think so either. This seems to be a non-issue.

Comment by Roman S. Borschel [ 26/Aug/10 ]

Unscheduled until we get further feedback.

Comment by Andriy Savchenko [ 16/Sep/10 ]

Roman,
I do not have this setup anymore so I cannot check next beta releases

Benjamin,
dash it is an allowed character for MySQL at least.

I do not think it is a big issue, it's just mater of your preferences - do you want to allow using of dash in the field names or not. If not may be it's a good idea to mention this fact somewhere in documentation

Comment by Benjamin Eberlei [ 20/Sep/10 ]

According to the SQL Error messages dashes dont seem to be allowed. Its exactly that character that causes the error message or not?

Hm, but dash seems to work. So it must be something else

Comment by Benjamin Eberlei [ 23/Sep/10 ]

This doesn't work because the persister uses the column-name for the AS part of the query. We won't fix this programatically, this is rather a restriction of Doctrine 2.

For this reason i have updated the documentation to state that non a-zA-Z0-9_ chars should not be used (even quoted) as columns.





[DDC-573] Provide generic resetDQLPart() and resetDQLParts() methods in QueryBuilder Created: 06/May/10  Updated: 23/Sep/10  Resolved: 23/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.0-BETA1
Fix Version/s: 2.0-RC1
Security Level: All

Type: Improvement Priority: Major
Reporter: Marc Hodgins Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

Given an existing instance of QueryBuilder, there appears to be no way to 'reset' most of the DQL parts. Usage example:

// reset single part
$queryBuilder->resetDQLPart('select');

// reset multiple parts
$queryBuilder->resetDQLParts(array('select', 'from'));

// reset all
$queryBuilder->resetDQLParts();

There are probably multiple use cases, but having the ability to reset parts of the DQL in QueryBuilder allows fine grained manipulation of an existing query (i.e. to build a two-part query to accomplish an efficient COUNT() query for pagination).

Suggested addition to QueryBuilder:

    /**
     * Reset DQL parts
     *
     * @param array $parts
     * @return QueryBuilder
     */
    public function resetDQLParts($parts = null)
    {
        if (is_null($parts)) {
            $parts = array_keys($this->_dqlParts);
        }
        foreach ($parts as $part) {
            $this->resetDQLPart($part);
        }
        return $this;
    }

    /**
     * Reset single DQL part
     *
     * @param string $part
     * @return QueryBuilder;
     */
    public function resetDQLPart($part)
    {
        if (is_array($this->_dqlParts[$part])) {
            $this->_dqlParts[$part] = array();
        } else {
            $this->_dqlParts[$part] = null;
        }
        $this->_state = self::STATE_DIRTY;
        return $this;
    }


 Comments   
Comment by Roman S. Borschel [ 07/May/10 ]

select(), where(), orderby(), groupby() etc. all replace existing parts, as opposed to their add* counterparts. I don't think we need such reset* methods (I also find such methods rather ugly in the API, no offense).

Concerning replacing "from", I am not sure. Is that really needed? I don't think that is already possible but it would be good to see concrete use-cases first.

Comment by Roman S. Borschel [ 07/May/10 ]

If you really want to "unset" and not "replace", creating a new QueryBuilder and then putting in the parts you want to reuse might also be a good idea.

Comment by Roman S. Borschel [ 07/May/10 ]

Found out that the generic add() method can basically be used to replace anything, even the from part. Just in case this is of any help.

Comment by Marc Hodgins [ 07/May/10 ]

@Roman thanks for the comments. add() allows you to replace (with one or more new DQL parts) but does not allow you to unset the parts. i.e. Once you have added an orderBy, you can't get it back to state where there is no orderBy in the query.

I could see use cases for resetting the join, groupBy and orderBy. At present it seems QueryBuilder is a one-way street and once you get it into certain states, you can't get it back out without calling getDQLParts() and manually copying each part to a new QueryBuilder. It shouldn't be that difficult.

// Given an existing $qb instance of QueryBuilder,
// run a COUNT() query to determine matching rows. 
// Removes the ORDER BY as it is not necessary for a COUNT().

// with a reset method
$qb2 = clone $qb; // don't modify existing query
$qb2->resetDQLPart('orderBy')->select('COUNT(DISTINCT a.id)');
$count = $qb2->getQuery()->getSingleScalarResult();

// without a reset method
$qb2 = new QueryBuilder($qb->getEntityManager());
$excludeParts = array('orderBy');
foreach ($qb->getDQLParts() as $partName => $partVal) {
    if (in_array($partName, $excludeParts)) {
        continue;
    }
    if (is_array($partVal)) {
        foreach ($partVal as $subPart) {
            $qb2->add($partName, $subPart, true);
        } 
    } else {
        $qb2->add($partName, $partVal);
    }
}
$count = $qb2->select('COUNT(DISTINCT a.id)')->getQuery()->getSingleScalarResult();
Comment by Roman S. Borschel [ 07/Aug/10 ]

Scheduling for 2.0 for now but I'd like to get more opinions on this.

Comment by Guilherme Blanco [ 12/Aug/10 ]

Initially I was against it. But I see some valid point on user request.
I don't have a formed opinion. Whatever you choose, I implement. =)

Comment by Benjamin Eberlei [ 12/Sep/10 ]

reset sounds good

Comment by Benjamin Eberlei [ 23/Sep/10 ]

Pushed into master





[DDC-759] More than one many-to-many relations cannot be created using default values Created: 19/Aug/10  Updated: 21/Sep/10  Resolved: 21/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Petr Motejlek Assignee: Roman S. Borschel
Resolution: Invalid Votes: 0
Labels: None


 Description   

An entity that has two many to many fields that referrence the same entity can't exist on its own, because ClassMetadataInfo uses the actual name of the referrenced entity to define joining table.

When there are for example Product and TextFile entities and you want to assigng the TextFile entitites to the Product entity firstly as descriptions (that are for example displayed on a product page) and secondly as simple text files (that can be downloaded on the product page, but are not displayed), ClassMetadataInfo tries to generate joining table called product_textfile for the descriptions field, then tries to generated joining table called product_textfile for the textfiles, but the latter will fail, because the product_textfile table already exists.

I propose that the table name generation strategy for many to many relations is changed so it will use the actual field name rather than the entity name. In the above example the joining tables would be product_descriptions and product_textFiles. I know that the standard naming conventions for database tables are not to use plurals, but I think it's better to use plurals and have those joining tables created automatically than not use them and have the user set names for the joining tables manually.

This new behaviour can be achieved by changing the file ClassMetadataInfo.php, line 837 from $targetShortName = substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '
') + 1); to $targetShortName = $mapping['fieldName'];



 Comments   
Comment by Benjamin Eberlei [ 21/Sep/10 ]

This will not be implemented, you can use:

/**
 * @JoinTable(name="other_name")
 * @ManyToMany(targetEntity="Foo")
 */




[DDC-809] ArrayHydrator and ObjectHydrator return different result sets for the same query Created: 16/Sep/10  Updated: 20/Sep/10  Resolved: 20/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Critical
Reporter: Andriy Savchenko Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 1
Labels: None
Environment:

Ubuntu 8.04.3, php 5.3.3, mysql 5.1



 Description   

I have many to many relation for 2 entities.

ArrayHydrator and ObjectHydrator return different result sets for the same query. Because of some reasons ObjectHydrator mises 2 records.

Code snippet and SQL to create database structure:

CREATE TABLE IF NOT EXISTS `specification_value_test` (
  `specification_value_id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`specification_value_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=96058 ;

INSERT INTO `specification_value_test` (`specification_value_id`) VALUES
(94506),
(94526),
(94564),
(94589),
(94593),
(94606),
(94607),
(94609),
(94711),
(94712),
(94780);


CREATE TABLE IF NOT EXISTS `variant_specification_value_test` (
  `variant_id` int(11) NOT NULL,
  `specification_value_id` int(11) NOT NULL,
  PRIMARY KEY (`variant_id`,`specification_value_id`),
  KEY `specification_value_id` (`specification_value_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `variant_specification_value_test` (`variant_id`, `specification_value_id`) VALUES
(545208, 94506),
(545209, 94506),
(545208, 94526),
(545209, 94526),
(545208, 94564),
(545209, 94564),
(545209, 94589),
(545209, 94593),
(545208, 94606),
(545209, 94606),
(545208, 94607),
(545209, 94607),
(545208, 94609),
(545209, 94609),
(545208, 94711),
(545208, 94712),
(545208, 94780),
(545209, 94780);

CREATE TABLE IF NOT EXISTS `variant_test` (
  `variant_id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`variant_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT AUTO_INCREMENT=545210 ;

INSERT INTO `variant_test` (`variant_id`) VALUES
(545208),
(545209);
/**
 * @Table(name="variant_test")
 * @Entity
 */
class Variant extends Base
{
    /**
     * @Column(name="variant_id", type="integer")
     * @Id
     * @GeneratedValue(strategy="AUTO")
     */
    protected $variantId;
    
    /**
     * @ManyToMany(targetEntity="SpecificationValue", inversedBy="Variants")
     * @JoinTable(name="variant_specification_value_test",
     *   joinColumns={
     *     @JoinColumn(name="variant_id", referencedColumnName="variant_id")
     *   },
     *   inverseJoinColumns={
     *     @JoinColumn(name="specification_value_id", referencedColumnName="specification_value_id")
     *   }
     * )
     */
    protected $SpecificationValues;
}

/**
 * @Table(name="specification_value_test")
 * @Entity
 */
class SpecificationValue
{
    /**
     * @Column(name="specification_value_id", type="integer")
     * @Id
     * @GeneratedValue(strategy="AUTO")
     */
    protected $specificationValueId;
    
    /**
     * @var Variant
     *
     * @ManyToMany(targetEntity="Variant", mappedBy="SpecificationValues")
     */
    protected $Variants;
}



$result = $em->createQueryBuilder()
    ->select('Variant, SpecificationValue')
    ->from('Variant', 'Variant')
    ->leftJoin('Variant.SpecificationValues', 'SpecificationValue')
    ->getQuery()
    ->getResult();
	
// returns 9 specification values for first variant and 7 specification values for second variant
\Doctrine\Common\Util\Debug($result, 4);

$em->createQueryBuilder()
    ->select('Variant, SpecificationValue')
    ->from('Variant', 'Variant')
    ->leftJoin('Variant.SpecificationValues', 'SpecificationValue')
    ->getQuery()
    ->getArrayResult();

// returns 9 specification values for first variant and 9 specification values for second variant
\Doctrine\Common\Util\Debug($result);


 Comments   
Comment by Benjamin Eberlei [ 20/Sep/10 ]

Fixed formatting

Comment by Benjamin Eberlei [ 20/Sep/10 ]

Verified and updated priority, has to be in RC1

Comment by Benjamin Eberlei [ 20/Sep/10 ]

Fixed the issue, thank you very much for reporting





[DDC-739] DQL generates wrong SQL if id column has other name Created: 09/Aug/10  Updated: 15/Sep/10  Resolved: 15/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.0-BETA3
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Alexey V. Ryazhskikh Assignee: Benjamin Eberlei
Resolution: Cannot Reproduce Votes: 0
Labels: None


 Description   

I created many to many relation User <-> Group same as CmsUser and CmsGroup in test.
But by User class has another definition for ID column:

 
class User
{
    /**
     * @Id @Column(name="Id", type="integer")
     * @GeneratedValue
     */
    private $id;
   ...

My DQL is:

 
$queryBuilder->select("g")->from("Group", "g")->join("g.users", "u");

It generates wrong sql:

SELECT g0_.Id AS Id0, g0_.name AS name1 FROM groups g0_ INNER JOIN users_groups u2_ ON g0_. = u2_.group_id INNER JOIN users u1_ ON u1_. = u2_.user_id

As you see g0_. has ho id column.
If I removes name="Id" from id column definition

 
class User
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    private $id;
   ...

all works fine and generated sql is:

SELECT g0_.id AS id0, g0_.name AS name1 FROM groups g0_ INNER JOIN users_groups u2_ ON g0_.id = u2_.group_id INNER JOIN users u1_ ON u1_.id = u2_.user_id


 Comments   
Comment by Guilherme Blanco [ 11/Aug/10 ]

Assigning to me

Comment by Guilherme Blanco [ 11/Aug/10 ]

Please public your Group and User mappings... I have tested here and could not reproduce the issue.

Cheers,

Comment by Benjamin Eberlei [ 15/Aug/10 ]

This is probably a bug on the other side missing a correct @joinColumn annotation?

Comment by Roman S. Borschel [ 30/Aug/10 ]

We need a complete (failing) unit test in order to proceed on this. Scheduling for RC1.

Comment by Benjamin Eberlei [ 15/Sep/10 ]

This is for sure an error in the @joinColumn specification (or no @joinColumn at all) i close this issue until further feedback is given.





[DDC-806] XSD requires an id element before the first field element Created: 15/Sep/10  Updated: 15/Sep/10  Resolved: 15/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Mapping Drivers
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Minor
Reporter: Manuel Strehl Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None
Environment:

Win XP + Cygwin, validating with xmlstar and xmllint


Attachments: XML File doctrine-xsd-test.dcm.xml    

 Description   

The entity element in doctrine-mapping.xsd requires an element id in front of the first element field.

This leads to invalid XML files, where a inherited class doesn't need an ID on its own, but inherits one from its parent.

In the examples in the documentation,
http://www.doctrine-project.org/projects/orm/2.0/docs/reference/xml-mapping/en#xml-element-reference:defining-fields
the code, too, has no id element in front of the first field elements.

A minimal example, showing the inheritance problem, too, is attached. The validation error occurs on the field element of the "Cat" entity.



 Comments   
Comment by Benjamin Eberlei [ 15/Sep/10 ]

Fixed





[DDC-802] Missing variable $name in XmlExporter Created: 14/Sep/10  Updated: 15/Sep/10  Resolved: 15/Sep/10

Status: Closed
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Critical
Reporter: Martin Hasoň Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None


 Description   

At line 112 http://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php#L112 is required variable $name. This variable should be replaced by $unique['name']. And before this line should be test if(isset($unique['name'])).



 Comments   
Comment by Guilherme Blanco [ 15/Sep/10 ]

On http://github.com/doctrine/doctrine2/commit/4845745337dbbed5eead25c3062a07103b38649f I fixed this issue.

Thanks for the report.





[DDC-749] positional query parameters throwing a QueryException Created: 17/Aug/10  Updated: 15/Sep/10  Resolved: 14/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA3
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Trivial
Reporter: Guillaume ORIOL Assignee: Roman S. Borschel
Resolution: Invalid Votes: 0
Labels: None
Environment:

MacOS 10.6.4/PHP 5.3.2



 Description   

I get the following exception:
"Invalid parameter number: number of bound variables does not match number of tokens"
when executing the following Doctrine query:

$em = $this->_getEntityManager();
$query = $em->createQuery('select e from Domain_Entity_Country e where e.alpha2Code like ?1');
$query->setParameters(array(1 => 'A%')); 


 Comments   
Comment by Benjamin Eberlei [ 12/Sep/10 ]

I cannot reproduce this sorry, can you retry with Beta4?

Comment by Guillaume ORIOL [ 14/Sep/10 ]

Hi Benjamin,

I made a new test and got the same error with BETA4.

Here is the stack trace:
Invalid parameter number: number of bound variables does not match number of tokens
#0 \/Users\/goriol\/src\/Doctrine\/doctrine-orm-2.0.0BETA4\/Doctrine\/ORM\/Query.php(229): Doctrine\\ORM\\Query
QueryException::invalidParameterNumber()
#1 \/Users\/goriol\/src\/Doctrine\/doctrine-orm-2.0.0BETA4\/Doctrine\/ORM\/AbstractQuery.php(528): Doctrine\\ORM
Query->_doExecute()
#2 \/Users\/goriol\/src\/Doctrine\/doctrine-orm-2.0.0BETA4\/Doctrine\/ORM\/AbstractQuery.php(408): Doctrine\\ORM
AbstractQuery->execute(Array, 4)
#3 \/Users\/goriol\/src\/Doctrine\/doctrine-orm-2.0.0BETA4\/Doctrine\/ORM\/AbstractQuery.php(434): Doctrine\\ORM
AbstractQuery->getSingleResult(4)
#4 \/Users\/goriol\/src\/DoctrineExtensions\/lib\/DoctrineExtensions\/Paginate\/PaginationAdapter.php(82): Doctrine\\ORM
AbstractQuery->getSingleScalarResult()
#5 \/Users\/goriol\/src\/DoctrineExtensions\/lib\/DoctrineExtensions\/Paginate\/PaginationAdapter.php(134): DoctrineExtensions\\Paginate\\PaginationAdapter->setRowCount(Object(Doctrine\\ORM
Query))
#6 \/Users\/goriol\/src\/Zend\/ZendFramework-1.10.5\/library\/Zend\/Paginator.php(1028): DoctrineExtensions\\Paginate
PaginationAdapter->count()
#7 \/Users\/goriol\/src\/Zend\/ZendFramework-1.10.5\/library\/Zend\/Paginator.php(712): Zend_Paginator->_calculatePageCount()
#8 \/Users\/goriol\/src\/Technema\/Service\/Doctrine.php(285): Zend_Paginator->setItemCountPerPage(30)
#9 \/Users\/goriol\/src\/Technema\/Controller\/Rest.php(85): Technema_Service_Doctrine->fetchPage(Array)
#10 \/Users\/goriol\/src\/Zend\/ZendFramework-1.10.5\/library\/Zend\/Controller\/Action.php(513): Technema_Controller_Rest->indexAction()
#11 \/Users\/goriol\/src\/Zend\/ZendFramework-1.10.5\/library\/Zend\/Controller\/Dispatcher\/Standard.php(295): Zend_Controller_Action->dispatch('indexAction')
#12 \/Users\/goriol\/src\/Zend\/ZendFramework-1.10.5\/library\/Zend\/Controller\/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#13 \/Users\/goriol\/src\/Zend\/ZendFramework-1.10.5\/library\/Zend\/Application\/Bootstrap\/Bootstrap.php(97): Zend_Controller_Front->dispatch()
#14 \/Users\/goriol\/src\/Zend\/ZendFramework-1.10.5\/library\/Zend\/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
#15 \/private\/var\/www\/erp.alterimago.com\/public\/index.php(24): Zend_Application->run()
#16

{main}
Comment by Benjamin Eberlei [ 14/Sep/10 ]

That stack trace puts the report in a new light, your code example is not really the source of the error but the pagination adapter is.

Comment by Benjamin Eberlei [ 14/Sep/10 ]

This is a Doctrine Extensions paginator bug, closing the issue here, its known in the extension already.

Comment by Guillaume ORIOL [ 14/Sep/10 ]

Are you talking about this issue?
http://github.com/beberlei/DoctrineExtensions/issues#issue/10

Comment by Benjamin Eberlei [ 15/Sep/10 ]

yes thats the one





[DDC-762] undefined index errors when the join-column of a relation is NULL Created: 21/Aug/10  Updated: 14/Sep/10  Resolved: 13/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: arnaud-lb Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Attachments: File patch.diff    

 Description   

When the value of the join-column of a relation is NULL, "undefined index" errors are thrown in UnitOfWork::createEntity().

The problem is in BasicEntityPersister::_processSQLResult() ; the attached diff fixed the problem for me.

I reproduce the problem with a code like this :
This triggers an error when the value of the column b_id is NULL.

<?php

class A {
  @Column(name="b_id", type="integer")
  private $bId;

  @OneToOne(targetEntity="B")
  @JoinColumn(name="b_id", referencedColumnName="id")
  private $b;
}

$entityManager->find('A', 1);
?>


 Comments   
Comment by Benjamin Eberlei [ 29/Aug/10 ]

fixed formating

Comment by Benjamin Eberlei [ 29/Aug/10 ]

This should either be fixed in MASTER, or is not an issue (redefine of the same column as key and relation). This will really only be possible with the experimental DDC-117 branch that will be merged for 2.1

Comment by arnaud-lb [ 29/Aug/10 ]

> not an issue (redefine of the same column as key and relation)

My example was not clear enough, the column is not a key.

<?php

class A {

  @Id
  private $id;

  // apart being a foreign key, this is not a key of A
  @Column(name="b_id", type="integer")
  private $bId;

  @OneToOne(targetEntity="B")
  @JoinColumn(name="b_id", referencedColumnName="id")
  private $b;
}

$entityManager->find('A', 1);
?>
Comment by Benjamin Eberlei [ 13/Sep/10 ]

problem is that array_key_exists is 9 times slower than isset, and this method is easily called several thousand times. We need to find another solution

Comment by Benjamin Eberlei [ 13/Sep/10 ]

@roman my proposed patch is this:

diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 242d84b..e3cd015 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -1881,7 +1881,7 @@ class UnitOfWork implements PropertyChangedListener
                         if ($assoc['isOwningSide']) {
                             $associatedId = array();
                             foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) {
-                                $joinColumnValue = $data[$srcColumn];
+                                $joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null;
                                 if ($joinColumnValue !== null) {
                                     $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue;
                                 }

it sucks this applies only to this use-case however...

Comment by Benjamin Eberlei [ 13/Sep/10 ]

Fixed

Comment by arnaud-lb [ 14/Sep/10 ]

Thanks!





[DDC-761] Associations between string fields result in mismatched column definitions on owning side Created: 20/Aug/10  Updated: 12/Sep/10  Resolved: 12/Sep/10

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

Type: Bug Priority: Major
Reporter: Marc Hodgins Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by DDC-755 Length of String column in a many to ... Resolved

 Description   

Using the latest master from github, defining a one-to-one or many-to-one relationship where the inverse side is a string of a specific length (i.e. other than the default 255 chars), the owning side column definition becomes a VARCHAR(255) (at least in MySQL) regardless of the length of the column on the other side of the relationship. I would expect the correct behavior would be for the column definitions to match on both sides. For example:

/** @Entity */
class foo {

    /**
     * @Id @Column(type="string", length=5)
     */
    protected $id;
}

/** @Entity */
class bar {
    /**
     * @Id @Column(type="integer")
     */
    protected $id;

    /**
     * @OneToOne(targetEntity="Foo")
     * @JoinColumn(name="foo_id", referencedColumnName="id")
     */
    protected $foo;
}

/** @Entity */
class baz {
    /**
     * @Id @Column(type="integer")
     */
    protected $id;

    /**
     * @ManyToOne(targetEntity="Foo")
     * @JoinColumn(name="foo_id", referencedColumnName="id")
     */
    protected $foo;
}

Resulting SQL from schematool:

CREATE TABLE foo (id VARCHAR(5) NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB;
CREATE TABLE bar (id INT NOT NULL, foo_id VARCHAR(255) DEFAULT NULL, UNIQUE INDEX bar_foo_id_uniq (foo_id), PRIMARY KEY(id)) ENGINE = InnoDB;
CREATE TABLE baz (id INT NOT NULL, foo_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) ENGINE = InnoDB;
ALTER TABLE bar ADD FOREIGN KEY (foo_id) REFERENCES foo(id);
ALTER TABLE baz ADD FOREIGN KEY (foo_id) REFERENCES foo(id)

Expected result:

CREATE TABLE foo (id VARCHAR(5) NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB;
CREATE TABLE bar (id INT NOT NULL, foo_id VARCHAR(5) DEFAULT NULL, UNIQUE INDEX bar_foo_id_uniq (foo_id), PRIMARY KEY(id)) ENGINE = InnoDB;
CREATE TABLE baz (id INT NOT NULL, foo_id VARCHAR(5) DEFAULT NULL, PRIMARY KEY(id)) ENGINE = InnoDB;
ALTER TABLE bar ADD FOREIGN KEY (foo_id) REFERENCES foo(id);
ALTER TABLE baz ADD FOREIGN KEY (foo_id) REFERENCES foo(id)

This bug is possibly related to DDC-755 except these associations don't involve integers.



 Comments   
Comment by Benjamin Eberlei [ 12/Sep/10 ]

fixed (should be!)





[DDC-748] BasicEntityPersister::refresh() broken with ManyToOne relationships Created: 16/Aug/10  Updated: 12/Sep/10  Resolved: 12/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA3
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Jasper Mattsson Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
Labels: None


 Description   

ManyToOne relationships are defined as an owning side of OneToOne relationships. This makes BasicEntityPersister to believe that it is refreshing a OneToOne relationship, resulting in the inverse end (collection) to be replaced with the entity being refreshed rather than a collection. (in BasicEntityPersister.php:662 in Beta 3)



 Comments   
Comment by Benjamin Eberlei [ 12/Sep/10 ]

Fixed!





[DDC-755] Length of String column in a many to many bi-directional is 255 chars Created: 18/Aug/10  Updated: 12/Sep/10  Resolved: 12/Sep/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA3
Fix Version/s: 2.0-RC1
Security Level: All

Type: Bug Priority: Major
Reporter: Alexander Trauzzi Assignee: Benjamin Eberlei
Resolution: Duplicate Votes: 0
Labels: None
Environment:

Ubuntu


Attachments: File Models.php    
Issue Links:
Duplicate
duplicates DDC-761 Associations between string fields re... Resolved

 Description   

As per discussion with Guilherme, I'm opening a ticket for when a bi-directional many to many relationship is established with one side having a string as its primary key, and the other having an integer.

It appears as though the ORM/DBAL are getting confused as to what the length of the invisible join table column between them should be.

In the case of my example models, when I use SchemaTool to generate the tables, it creates a BlogPost table with the column blog_name with a length of 255 characters (it should be 40). When I use the SchemaTool to generate an update to the table, it tells me it wants to modify the column to be 255 characters in spite the facts that:

1) It already is.
2) It's wrong.



 Comments   
Comment by Benjamin Eberlei [ 12/Sep/10 ]

This issue is a duplicate of DDC-761





Generated at Fri Oct 24 15:27:30 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.