Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DDC-149: No owner found for field when selecting from a table with @InheritanceType SINGLE_TABLE #2118

Closed
doctrinebot opened this issue Nov 16, 2009 · 16 comments
Labels
Milestone

Comments

@doctrinebot
Copy link

Jira issue originally created by user rickdt:

In class AbstractHydrator::_gatherScalarRowData, I get an exception when the result contain metaMappings.

The problem is that $fieldName is empty when obtained this way :
$fieldName = $this->_rsm->fieldMappings[$key];

I think you should also check into :
$this->_rsm->metaMappings[$key];

May a better way would be to add a public function to ResultSetMapping like getMappedFieldName() which would look into both properties.

Here is the exception :
#0 [internal function]: Doctrine\Common\DoctrineException::**callStatic('noOwnerFoundFor...', Array)
#1 /home/eric/Zend/workspaces/DefaultWorkspace7/fna/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php(316): Doctrine\Common\DoctrineException::noOwnerFoundForField(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL)
#2 /home/eric/Zend/workspaces/DefaultWorkspace7/fna/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php(267): Doctrine\ORM\Internal\Hydration\AbstractHydrator->_lookupDeclaringClass(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL)
#3 /home/eric/Zend/workspaces/DefaultWorkspace7/fna/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php(42): Doctrine\ORM\Internal\Hydration\AbstractHydrator->_gatherScalarRowData(Array, Array)
#4 /home/eric/Zend/workspaces/DefaultWorkspace7/fna/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php(103): Doctrine\ORM\Internal\Hydration\ScalarHydrator->_hydrateAll()
#5 /home/eric/Zend/workspaces/DefaultWorkspace7/fna/lib/Doctrine/ORM/AbstractQuery.php(497): Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll(Object(Doctrine\DBAL\Driver\PDOStatement), Object(Doctrine\ORM\Query\ResultSetMapping), Array)
#6 /home/eric/Zend/workspaces/DefaultWorkspace7/fna/lib/Doctrine/ORM/AbstractQuery.php(361): Doctrine\ORM\AbstractQuery->execute(Array, 3)
#7 /home/eric/Zend/workspaces/DefaultWorkspace7/fna/application/Kronos/FNA/View/FNA/FNAList.php(99): Doctrine\ORM\AbstractQuery->getScalarResult()

@doctrinebot
Copy link
Author

Comment created by romanb:

Can you give us some code to reproduce?

@doctrinebot
Copy link
Author

Comment created by rickdt:

I did not test with this, but here is a simplified version of my entity classes et my query.

namespace BaseEntity;

/****
 * @MappedSuperclass
 * @HasLifecycleCallbacks
 */
class Revisionable extends BaseEntity\Entity
{

    /****
     * @Column(name="rev_type", type="string")
     */
    protected $rev_type='';
}
namespace Entity;

/****
 * @Entity
 * @Table(name="fna_fna")
 * @HasLifecycleCallbacks
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="rev_type", type="string")
 * @DiscriminatorMap({"HEAD" = "Entity\FNA", "REVISION" = "RevisionEntity\FNA"})
 */
class FNA extends \Kronos\FNA\ORM\BaseEntity\FNA
{

}
namespace RevisionEntity;

/****
 * @Entity
 * @Table(name="fna_fna")
 */
class FNA extends BaseEntity\FNA{


}
namespace BaseEntity;

/****
 * @MappedSuperclass
 * @HasLifecycleCallbacks
 */
class FNA extends Revisionable
{

    /****
     * @Column(name="status", type="string", length="25")
     */
    protected $status;

}
$qb->select('fna.id', 'fna.status')
            ->from('Entity\FNA', 'fna')
            ->groupBy('fna.id');

@doctrinebot
Copy link
Author

Comment created by rickdt:

This comment have been moved to DDC-150


I have another major problem with the same class. I can open an other case if you want.

The discriminator value column is lost after querying on an object.

Before this, $rev_type field equal "HEAD". After, it is empty string.

$qb = new \Doctrine\ORM\QueryBuilder($em);
        $qb->select('fna')
            ->from('Entity\FNA', 'fna')
            ->andwhere($qb->expr()->eq('fna.id', ':fna_id'));
        $qb->setParameter('fna_id', 1);
        $query = $qb->getQuery();

        $fna = $query->getSingleResult();
        $em->flush();

@doctrinebot
Copy link
Author

Comment created by romanb:

Why do you map the discriminator column to a property? Just like foreign keys its not intended to be visible in your classes, its a detail of the relational database.

@doctrinebot
Copy link
Author

Comment created by rickdt:

I did this trying to workaround the bug.

@doctrinebot
Copy link
Author

Comment created by rickdt:

If I remove the discriminator column from the entity, I still get the "No owner found for field" error and the proposed fix (look into meta mapping) does not work.

Maybe the field should just be ignored.

@doctrinebot
Copy link
Author

Comment created by rickdt:

Are you OK to investigate on this or you need more input from me ?

I may also simulate this behavior at application level if you tell me this feature is too far away from being ready for use.

@doctrinebot
Copy link
Author

Comment created by romanb:

There are still some things that are unclear to me.

  1. You're talking of AbstractHydrator::_gatherScalarRowData but the query you've shown is not scalar. What do you use to get the result? ->getScalarResult()?

  2. The exception noOwnerFoundForField... should contain the name of the field and possible the class that causes the problem. Can you show the full exception message?

  3. The line numbers in the stack trace dont seem to match with mine. What version/revision are you using?

A failing test case would be best. That means either a phpunit test or a small functional version as an attachment that reproduces the issue.

Thanks for your help.

@doctrinebot
Copy link
Author

Comment created by romanb:

OK, my first question is answered when looking at the stack trace. So you use getScalarResult.

@doctrinebot
Copy link
Author

Comment created by romanb:

I will try to make a test for Single Table Inheritance + getScalarResult in our test suite. Maybe this shows the issue already.

I will report back as soon as I have more questions.

@doctrinebot
Copy link
Author

Comment created by rickdt:

  1. The comment at 16/Nov/09 02:40 PM is not related to this issue. I should have created an other issue.

  2. That's because fieldName is empty. (It does not exists in $this->_rsm->fieldMappings)

  3. I removed the last lines of the stack trace because they where related to my project. (I use revision 6727)

For the test case. This represent quiet some work and if it's not absolutely necessary, I prefer not do it.

Thank You!

@doctrinebot
Copy link
Author

Comment created by rickdt:

For the line numbers in the stack trace, I just understood your question.

Line number are different because I added some debugging output.

@doctrinebot
Copy link
Author

Comment created by rickdt:

Got it !

That was so simpe, I dont't know why we did not see it.

*gatherScalarRowData is missing a case that is properly handled by *gatherRowData

 if (isset($this->_rsm->fieldMappings[$key])) {
                    $classMetadata = $this->*em->getClassMetadata($this->*rsm->getOwningClass($key));
                    $fieldName = $this->_rsm->fieldMappings[$key];
                    if ( ! isset($classMetadata->reflFields[$fieldName])) {
                        $classMetadata = $this->_lookupDeclaringClass($classMetadata, $fieldName);
                    }
                    $cache[$key]['fieldName'] = $fieldName;
                    $cache[$key]['isScalar'] = false;
                    $cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
                    $cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
                    $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
                } else {
                    // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
                    $cache[$key]['isMetaColumn'] = true;
                    $cache[$key]['isScalar'] = false;
                    $cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
                    $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
                }

@doctrinebot
Copy link
Author

Comment created by rickdt:

This fix the issue

@doctrinebot
Copy link
Author

Issue was closed with resolution "Fixed"

@doctrinebot doctrinebot added this to the 2.0-ALPHA4 milestone Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
@doctrinebot
Copy link
Author

Imported 1 attachments from Jira into https://gist.github.com/8d6b5470301d470a8d11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant