Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Serializing process doesn't support indexBy with association #504

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

Closed
soundlake opened this issue Dec 29, 2017 · 17 comments
Closed

Serializing process doesn't support indexBy with association #504

soundlake opened this issue Dec 29, 2017 · 17 comments
Labels

Comments

@soundlake
Copy link

soundlake commented Dec 29, 2017

symfony/symfony: v3.4.2
doctrine/orm: v2.5.14
api-platform/core: v2.1.4

Hello, I have a structure like following:

class User
{
    /**
     * @ORM\OneToMany(targetEntity="ExtraInfo", mappedBy="user")
     */
    private $extra_infos;

    ...
}

class ExtraField
{
    /**
     * @ORM\OneToMany(targetEntity="ExtraInfo", mappedBy="field")
     */
    private $extra_infos;

    ...
}

class ExtraInfo
{
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="User", inversedBy="extra_infos")
     */
    private $user;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="ExtraField", inversedBy="extra_infos")
     */
    private $field;

    ...
}

In such case, API-Platform shows only ExtraInfo->user as the id of ExtraInfo. It doesn't show ExtraInfo->field as its id.

@soundlake
Copy link
Author

Also, it doesn't support indexBy with association.

In the same example, if I set indexBy with ExtraInfo->field, then it crashes with InvalidArgumentException with "" is not a valid PHP type. message from vendor/symfony/symfony/src/Symfony/Component/PropertyInfo/Type.php

class User
{
    /**
     * @ORM\OneToMany(targetEntity="ExtraInfo", mappedBy="user", indexBy="field_id")
     */
    private $extra_infos;

    ...
}

@soyuka
Copy link
Member

soyuka commented Dec 29, 2017

We have a test case with id on associations and it should work.

@soundlake
Copy link
Author

@soyuka Thank you. I found RelatedToDummyFriend in the test fixtures. I check the code and apply them and check what was the problem.

@soundlake
Copy link
Author

@soyuka I've grep on core/tests for RelatedToDummyFriend, but I got nothing. :/ Are you sure if you have the test case?

@soyuka
Copy link
Member

soyuka commented Dec 30, 2017

Check in the features, I'm also using this kind of entities myself a lot.

@soundlake
Copy link
Author

@soyuka I tested around and it gets problematic when I put indexBy.

class User
{
    /**
     * @ORM\OneToMany(targetEntity="ExtraInfo", mappedBy="user", indexBy="field_id")
     */
    private $extra_infos;

    ...
}

If I remove indexBy, then Doctrine gives me an ArrayCollection with auto-incremented keys, which is a PITA because I should traverse the ArrayCollection to check if the ExtraInfo exists. If I put indexBy, then API-Platform gives me an InvalidArgumentException with "" is not a valid PHP type.

@soundlake soundlake changed the title Api-Platform's serializer doesn't support id with multiple association Serializing process doesn't support indexBy with association Jan 2, 2018
@soyuka
Copy link
Member

soyuka commented Jan 4, 2018

Can we get a bit more detailed stack trace on this error? Thanks!

@soundlake
Copy link
Author

@soyuka Here it is.

InvalidArgumentException
"" is not a valid PHP type.
 in vendor/symfony/symfony/src/Symfony/Component/PropertyInfo/Type.php (line 72)
at Symfony\Component\PropertyInfo\Type->__construct(null) in vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php (line 110)
at Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor->getTypes('AppBundle\\Entity\\ExtraInfo', 'extraInfos', array())
at call_user_func_array(array(object(Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor), 'getTypes'), array('AppBundle\\Entity\\User', 'extraInfos', array())) in vendor/symfony/symfony/src/Symfony/Component/P
at Symfony\Component\PropertyInfo\PropertyInfoExtractor->extract(object(Symfony\Component\DependencyInjection\Argument\RewindableGenerator), 'getTypes', array('AppBundle\\Entity\\User', 'extraInfos', array())) in
at Symfony\Component\PropertyInfo\PropertyInfoExtractor->getTypes('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Bridge/Symfony/PropertyInfo/Metadata/Property/PropertyInfoPropert
at ApiPlatform\Core\Bridge\Symfony\PropertyInfo\Metadata\Property\PropertyInfoPropertyMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Metadata/Property/Fac
at ApiPlatform\Core\Metadata\Property\Factory\InheritedPropertyMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Metadata/Property/Factory/AnnotationProperty
at ApiPlatform\Core\Metadata\Property\Factory\AnnotationPropertyMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Metadata/Property/Factory/ExtractorProperty
at ApiPlatform\Core\Metadata\Property\Factory\ExtractorPropertyMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Bridge/Doctrine/Orm/Metadata/Property/Doctri
at ApiPlatform\Core\Bridge\Doctrine\Orm\Metadata\Property\DoctrineOrmPropertyMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Metadata/Property/Factory/Seri
at ApiPlatform\Core\Metadata\Property\Factory\SerializerPropertyMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Metadata/Property/Factory/AnnotationSubreso
at ApiPlatform\Core\Metadata\Property\Factory\AnnotationSubresourceMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Bridge/Symfony/Validator/Metadata/Proper
at ApiPlatform\Core\Bridge\Symfony\Validator\Metadata\Property\ValidatorPropertyMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos', array()) in vendor/api-platform/core/src/Metadata/Property/Factory/C
at ApiPlatform\Core\Metadata\Property\Factory\CachedPropertyMetadataFactory->create('AppBundle\\Entity\\User', 'extraInfos') in vendor/api-platform/core/src/Operation/Factory/SubresourceOperationFactory.php (line
at ApiPlatform\Core\Operation\Factory\SubresourceOperationFactory->computeSubresourceOperations('AppBundle\\Entity\\User', array()) in vendor/api-platform/core/src/Operation/Factory/SubresourceOperationFactory.php
at ApiPlatform\Core\Operation\Factory\SubresourceOperationFactory->create('AppBundle\\Entity\\User') in vendor/api-platform/core/src/Operation/Factory/CachedSubresourceOperationFactory.php (line 52)
at ApiPlatform\Core\Operation\Factory\CachedSubresourceOperationFactory->create('AppBundle\\Entity\\User') in vendor/api-platform/core/src/Bridge/Symfony/Routing/ApiLoader.php (line 102)
at ApiPlatform\Core\Bridge\Symfony\Routing\ApiLoader->load('.', 'api_platform') in vendor/symfony/symfony/src/Symfony/Component/Config/Loader/FileLoader.php (line 153)
at Symfony\Component\Config\Loader\FileLoader->doImport('.', 'api_platform', false, '/opt/beip-bx/bx/config/routing.yml') in vendor/symfony/symfony/src/Symfony/Component/Config/Loader/FileLoader.php (line 90)
at Symfony\Component\Config\Loader\FileLoader->import('.', 'api_platform', false, '/opt/beip-bx/bx/config/routing.yml') in vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/YamlFileLoader.php (line 161)
at Symfony\Component\Routing\Loader\YamlFileLoader->parseImport(object(Symfony\Component\Routing\RouteCollection), array('resource' => '.', 'type' => 'api_platform', 'prefix' => '/api/0.2'), '/opt/beip-bx/bx/confi
at Symfony\Component\Routing\Loader\YamlFileLoader->load('/opt/beip-bx/bx/config/routing.yml', null) in vendor/symfony/symfony/src/Symfony/Component/Config/Loader/FileLoader.php (line 153)
at Symfony\Component\Config\Loader\FileLoader->doImport('/opt/beip-bx/bx/config/routing.yml', null, false, '/opt/beip-bx/bx/config/routing_dev.yml') in vendor/symfony/symfony/src/Symfony/Component/Config/Loader/Fi
at Symfony\Component\Config\Loader\FileLoader->import('routing.yml', null, false, '/opt/beip-bx/bx/config/routing_dev.yml') in vendor/symfony/symfony/src/Symfony/Component/Routing/Loader/YamlFileLoader.php (line 1
at Symfony\Component\Routing\Loader\YamlFileLoader->parseImport(object(Symfony\Component\Routing\RouteCollection), array('resource' => 'routing.yml'), '/opt/beip-bx/bx/config/routing_dev.yml', '/opt/beip-bx/bx/con
at Symfony\Component\Routing\Loader\YamlFileLoader->load('/opt/beip-bx/bx/config/routing_dev.yml', null) in vendor/symfony/symfony/src/Symfony/Component/Config/Loader/DelegatingLoader.php (line 40)
at Symfony\Component\Config\Loader\DelegatingLoader->load('/opt/beip-bx/bx/config/routing_dev.yml', null) in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php (line 70)
at Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader->load('/opt/beip-bx/bx/config/routing_dev.yml', null) in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php (line 56)
at Symfony\Bundle\FrameworkBundle\Routing\Router->getRouteCollection() in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php (line 367)
at Symfony\Component\Routing\Router->getMatcherDumperInstance() in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php (line 289)
at Symfony\Component\Routing\Router->Symfony\Component\Routing\{closure}(object(Symfony\Component\Config\ResourceCheckerConfigCache))
at call_user_func(object(Closure), object(Symfony\Component\Config\ResourceCheckerConfigCache)) in vendor/symfony/symfony/src/Symfony/Component/Config/ResourceCheckerConfigCacheFactory.php (line 43)
at Symfony\Component\Config\ResourceCheckerConfigCacheFactory->cache('/opt/beip-bx/cache/sf2/bxDevDebugProjectContainerUrlMatcher.php', object(Closure)) in vendor/symfony/symfony/src/Symfony/Component/Routing/Rout
at Symfony\Component\Routing\Router->getMatcher() in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php (line 256)
at Symfony\Component\Routing\Router->matchRequest(object(Symfony\Component\HttpFoundation\Request)) in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php (line 109)
at Symfony\Component\HttpKernel\EventListener\RouterListener->onKernelRequest(object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', object(Symfony\Component\HttpKernel\Debug\TraceableEvent
at call_user_func(array(object(Symfony\Component\HttpKernel\EventListener\RouterListener), 'onKernelRequest'), object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', object(Symfony\Componen
at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(Symfony\Component\HttpKernel\Event\GetResponseEvent), 'kernel.request', object(Symfony\Component\EventDispatcher\ContainerAwareEventDispa
at Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(array(object(Symfony\Component\EventDispatcher\Debug\WrappedListener), object(Symfony\Component\EventDispatcher\Debug\WrappedListener), object(Symfo
at Symfony\Component\EventDispatcher\EventDispatcher->dispatch('kernel.request', object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/T
at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch('kernel.request', object(Symfony\Component\HttpKernel\Event\GetResponseEvent)) in vendor/symfony/symfony/src/Symfony/Component/HttpKern
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Symfony\Component\HttpFoundation\Request), 1) in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php (line 68)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Symfony\Component\HttpFoundation\Request), 1, true) in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php (line 202)

@soundlake
Copy link
Author

I didn't know Github has fixed max width of a line. I tested putting the trace into Gist, but it didn't work, either. :/

@soundlake
Copy link
Author

Any advice?

@soyuka
Copy link
Member

soyuka commented Jan 15, 2018

It's really weird that Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor->getTypes('AppBundle\\Entity\\ExtraInfo', 'extraInfos', array()) doesn't find anything (then it calls new Type(null) which fails here). I'm not sure it has something to do with indexBy. Do you have getter / setter for this?

@soundlake
Copy link
Author

soundlake commented Jan 15, 2018

The property is private and I have getter, getExtraInfos(), but I don't have setter. I have addExtraInfo(ExtraInfo $extraInfo) and removeExtraInfo(ExtraInfo $extraInfo) instead. Is it something to do with the setter?
I've just tried, but I got same error message.

@soundlake
Copy link
Author

I totally agree that it's really weird.

@soyuka
Copy link
Member

soyuka commented Jan 15, 2018

The property is private and I have getter, getExtraInfos(), but I don't have setter. I have addExtraInfo(ExtraInfo $extraInfo) and removeExtraInfo(ExtraInfo $extraInfo) instead. Is it something to do with the setter?

Nope that's fine. ExtraInfo is also an entity?

@soundlake
Copy link
Author

Yes, it's also an entity. ExtraField which is eager to be the key, too.

@insekticid
Copy link
Contributor

symfony/symfony#25841

@Simperfit
Copy link
Contributor

This should be updated when the symfony's PR will be merged ;).

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

5 participants