[DDC-2370] Subclass annotations not being read, unable to use OneToMany relation with single table inheritance Created: 26/Mar/13  Updated: 01/May/13  Resolved: 01/May/13

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

Type: Bug Priority: Major
Reporter: Arthur Bodera Assignee: Benjamin Eberlei
Resolution: Invalid Votes: 0
Labels: annotationdriver, inheritance, orm
Environment:

PHP 5.4.11



 Description   

Subclasses that override parent class properties and define relations will not work as expected, because AnnotationDriver/Reader will only use the parent class annotation (discarding whatever subclass defined).

The following code will produce error:

[Mapping]  FAIL - The entity-class 'Test\Office' mapping is invalid:
* The mappings Test\Office#employees and Employee#office are incosistent with each other.

Test code:

<?php
namespace Test;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * @ORM\Entity
 */
class Office 
{
    /**
     * @ORM\OneToMany(targetEntity="Person", mappedBy="office")
     * @var Person[]|ArrayCollection
     */
    protected $people;
 
    /**
     * @ORM\OneToMany(targetEntity="Employee", mappedBy="office")
     * @var Employee[]|ArrayCollection
     */
    protected $employees;
 
}
 
/**
 * @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({"employee" = "Employee"})
 */
class Person
{
    /**
     * @ORM\ManyToOne(targetEntity="Office", inversedBy="people")
     * @var Office
     */
    protected $office;
}
 
/**
 * @ORM\Entity
 */
class Employee extends Person
{
    /**
     * @ORM\ManyToOne(targetEntity="Office", inversedBy="employees")
     * @var Office
     */
    protected $office;
}


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

Overwriting assocations in this way is not supported.

Comment by Arthur Bodera [ 01/May/13 ]

Ok, I get that it's not supported right now, but why did you mark it as resolved?





[DCOM-165] Entities seems not be recognized by AnnotationDriver Created: 02/Sep/12  Updated: 23/Jan/13

Status: Open
Project: Doctrine Common
Component/s: Annotations
Affects Version/s: 2.2, 2.3
Fix Version/s: None

Type: Bug Priority: Trivial
Reporter: Maarten de Keizer Assignee: Marco Pivetta
Resolution: Unresolved Votes: 0
Labels: annotationdriver, realpath, symlink, windows
Environment:

Windows 7 Profesional, Enterprise and Windows Server 2003 and 2008; Common: 2.2.3 DBAL: 2.2.2 ORM: 2.2.3; PHP 5.4.5 and 5.3.5



 Description   

Problem:
--------
"$em->getMetadataFactory()->getAllMetadata()"
Will result in an empty array. The entitiy manager is correctly configured and the entities files are loaded (echo's in the files will be displayed).

Debug steps:
------------
Looking in the code for the problem I created the following debug points first:

file AnnotationDriver.php method getAllClassNames()
after the line: "$includedFiles[] = $sourceFile;"
add: "echo $sourceFile . ' is loaded' . PHP_EOL;"

file AnnotationDriver.php method getAllClassNames()
after the line: "$sourceFile = $rc->getFileName();"
add: "echo $className . ' is loaded from: ' . $sourceFile . ' in the includedFiles array? ' . (in_array($sourceFile, $includedFiles) ? 'YES' : 'not found ') . PHP_EOL;"

the following output will be displayed:
...
f:\workspace\nl.markei.posto-2.3\lib\relaties\Contact.php is loaded
...
nl\markei\posto\relaties\Contact is loaded from: F:\workspace\nl.markei.posto-2.3\lib\relaties\Contact.php in the includedFiles array? not found

It seems that Doctrine includes the file from f: but ReflectionClass say it is loaded from F:. The in_array() will fail and Doctrine will not recognized the entity.

But this is not the full problem. I created a new debug point:

file AnnotationDriver.php method getAllClassNames()
after the line: "foreach ($this->_paths as $path) {"
add: "echo 'path: ' . $path . ' after realpath: ' . realpath($path) . PHP_EOL;"

This will result in the following output:
"path: F:\domains\markei.nl\lib\nl.markei.posto\ after realpath: f:\workspace\nl.markei.posto-2.3\lib"

So the conversion of the F: to f: is done by realpath; its look like

A simple fix should be in AnnotationDriver.php / getAllClassNames()
replace: "$sourceFile = $rc->getFileName();"
by: "$sourceFile = realpath($rc->getFileName());"

After I did that, the problem still exists. So I add to echo's (one with realpath and one without at the part of the code). And both echo's result in a path starting with "F:".

So my first reaction was freaky!

After some frustrating hours I found the problem in the symlink I used.
"F:\domains\markei.nl\lib\nl.markei.posto" was a symlink to "f:\workspace\nl.markei.posto-2.3\lib" and realpath will not convert the driver char in the target of the symlink for some freaky reason. After changing the symlink target to "F:\workspace...." everything works fine.

Summary:
--------
realpath results are not consistent on Windows. This will resulting in problems under Windows.

Possible solutions:
-------------------
Saying "this is a PHP bug".
It is possible that there are more case sensitive problems hidding here on Windows. Maybe it is better to use (for Windows only!) a case insensitive in_array-alternative in AnnotationDriver.php getAllClassNames() (or convert all paths for to lowercase for Windows)



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

Maarten de Keizer looks like the issue is still there in doctrine/annotations. Are you able to come up with a failing test case?





Generated at Mon May 20 01:50:21 UTC 2013 using JIRA 5.2.7#850-sha1:b2af0c8dc8537b36121c6a579fabbdf79fc919e5.