Description
Symfony version(s) affected: 5.1.2
Description
It seems to be the same bug as #31775, which was fixed with #32107.
I try to post to an Resource which has an address embeddable. Validating the country of the embeddable gives me this error:
{ "@context": "/api/contexts/Error", "@type": "hydra:Error", "hydra:title": "An error occurred", "hydra:description": "Property \"country\" does not exist in class \"MWS\\CustomerBundle\\Entity\\CustomerAddress\".", "trace": [ { "namespace": "", "short_class": "", "class": "", "type": "", "function": "", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Mapping/PropertyMetadata.php", "line": 40, "args": [] }, { "namespace": "Symfony\\Component\\Validator\\Mapping", "short_class": "PropertyMetadata", "class": "Symfony\\Component\\Validator\\Mapping\\PropertyMetadata", "type": "->", "function": "__construct", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Mapping/ClassMetadata.php", "line": 208, "args": [ [ "string", "MWS\\CustomerBundle\\Entity\\CustomerAddress" ], [ "string", "country" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Mapping", "short_class": "ClassMetadata", "class": "Symfony\\Component\\Validator\\Mapping\\ClassMetadata", "type": "->", "function": "addPropertyConstraint", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php", "line": 220, "args": [ [ "string", "country" ], [ "object", "Symfony\\Component\\Validator\\Constraints\\NotBlank" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Mapping\\Loader", "short_class": "XmlFileLoader", "class": "Symfony\\Component\\Validator\\Mapping\\Loader\\XmlFileLoader", "type": "->", "function": "loadClassMetadataFromXml", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php", "line": 44, "args": [ [ "object", "Symfony\\Component\\Validator\\Mapping\\ClassMetadata" ], [ "object", "SimpleXMLElement" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Mapping\\Loader", "short_class": "XmlFileLoader", "class": "Symfony\\Component\\Validator\\Mapping\\Loader\\XmlFileLoader", "type": "->", "function": "loadClassMetadata", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Mapping/Loader/LoaderChain.php", "line": 54, "args": [ [ "object", "Symfony\\Component\\Validator\\Mapping\\ClassMetadata" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Mapping\\Loader", "short_class": "LoaderChain", "c
9BD6
lass": "Symfony\\Component\\Validator\\Mapping\\Loader\\LoaderChain", "type": "->", "function": "loadClassMetadata", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php", "line": 101, "args": [ [ "object", "Symfony\\Component\\Validator\\Mapping\\ClassMetadata" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Mapping\\Factory", "short_class": "LazyLoadingMetadataFactory", "class": "Symfony\\Component\\Validator\\Mapping\\Factory\\LazyLoadingMetadataFactory", "type": "->", "function": "getMetadataFor", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php", "line": 122, "args": [ [ "string", "MWS\\CustomerBundle\\Entity\\CustomerAddress" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Mapping\\Factory", "short_class": "LazyLoadingMetadataFactory", "class": "Symfony\\Component\\Validator\\Mapping\\Factory\\LazyLoadingMetadataFactory", "type": "->", "function": "mergeConstraints", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php", "line": 109, "args": [ [ "object", "Symfony\\Component\\Validator\\Mapping\\ClassMetadata" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Mapping\\Factory", "short_class": "LazyLoadingMetadataFactory", "class": "Symfony\\Component\\Validator\\Mapping\\Factory\\LazyLoadingMetadataFactory", "type": "->", "function": "getMetadataFor", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Validator/RecursiveContextualValidator.php", "line": 306, "args": [ [ "object", "MWS\\CustomerBundle\\Entity\\DeliveryAddress" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Validator", "short_class": "RecursiveContextualValidator", "class": "Symfony\\Component\\Validator\\Validator\\RecursiveContextualValidator", "type": "->", "function": "validateObject", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Validator/RecursiveContextualValidator.php", "line": 138, "args": [ [ "object", "MWS\\CustomerBundle\\Entity\\DeliveryAddress" ], [ "string", "" ], [ "array", [ [ "string", "Address" ] ] ], [ "integer", 1 ], [ "object", "Symfony\\Component\\Validator\\Context\\ExecutionContext" ] ] }, { "namespace": "Symfony\\Component\\Validator\\Validator", "short_class": "RecursiveContextualValidator", "class": "Symfony\\Component\\Validator\\Validator\\RecursiveContextualValidator", "type": "->", "function": "validate", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Validator/RecursiveValidator.php", "line": 93, "args": [ [ "object", "MWS\\CustomerBundle\\Entity\\DeliveryAddress" ], [ "null", null ], [ "array", [ [ "string", "Address" ] ] ] ] }, { "namespace": "Symfony\\Component\\Validator\\Validator", "short_class": "RecursiveValidator", "class": "Symfony\\Component\\Validator\\Validator\\RecursiveValidator", "type": "->", "function": "validate", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/validator/Validator/TraceableValidator.php", "line": 66, "args": [ [ "object", "MWS\\CustomerBundle\\Entity\\DeliveryAddress" ], [ "null", null ], [ "array", [ [ "string", "Address" ] ] ] ] }, { "namespace": "Symfony\\Component\\Validator\\Validator", "short_class": "TraceableValidator", "class": "Symfony\\Component\\Validator\\Validator\\TraceableValidator", "type": "->", "function": "validate", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/api-platform/core/src/Bridge/Symfony/Validator/Validator.php", "line": 61, "args": [ [ "object", "MWS\\CustomerBundle\\Entity\\DeliveryAddress" ], [ "null", null ], [ "array", [ [ "string", "Address" ] ] ] ] }, { "namespace": "ApiPlatform\\Core\\Bridge\\Symfony\\Validator", "short_class": "Validator", "class": "ApiPlatform\\Core\\Bridge\\Symfony\\Validator\\Validator", "type": "->", "function": "validate", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/api-platform/core/src/Validator/EventListener/ValidateListener.php", "line": 68, "args": [ [ "object", "MWS\\CustomerBundle\\Entity\\DeliveryAddress" ], [ "array", { "groups": [ "array", [ [ "string", "Address" ] ] ] } ] ] }, { "namespace": "ApiPlatform\\Core\\Validator\\EventListener", "short_class": "ValidateListener", "class": "ApiPlatform\\Core\\Validator\\EventListener\\ValidateListener", "type": "->", "function": "onKernelView", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/event-dispatcher/Debug/WrappedListener.php", "line": 117, "args": [ [ "object", "Symfony\\Component\\HttpKernel\\Event\\ViewEvent" ], [ "string", "kernel.view" ], [ "object", "Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher" ] ] }, { "namespace": "Symfony\\Component\\EventDispatcher\\Debug", "short_class": "WrappedListener", "class": "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener", "type": "->", "function": "__invoke", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/event-dispatcher/EventDispatcher.php", "line": 230, "args": [ [ "object", "Symfony\\Component\\HttpKernel\\Event\\ViewEvent" ], [ "string", "kernel.view" ], [ "object", "Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher" ] ] }, { "namespace": "Symfony\\Component\\EventDispatcher", "short_class": "EventDispatcher", "class": "Symfony\\Component\\EventDispatcher\\EventDispatcher", "type": "->", "function": "callListeners", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/event-dispatcher/EventDispatcher.php", "line": 59, "args": [ [ "array", [ [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ], [ "object", "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener" ] ] ], [ "string", "kernel.view" ], [ "object", "Symfony\\Component\\HttpKernel\\Event\\ViewEvent" ] ] }, { "namespace": "Symfony\\Component\\EventDispatcher", "short_class": "EventDispatcher", "class": "Symfony\\Component\\EventDispatcher\\EventDispatcher", "type": "->", "function": "dispatch", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php", "line": 151, "args": [ [ "object", "Symfony\\Component\\HttpKernel\\Event\\ViewEvent" ], [ "string", "kernel.view" ] ] }, { "namespace": "Symfony\\Component\\EventDispatcher\\Debug", "short_class": "TraceableEventDispatcher", "class": "Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher", "type": "->", "function": "dispatch", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/http-kernel/HttpKernel.php", "line": 162, "args": [ [ "object", "Symfony\\Component\\HttpKernel\\Event\\ViewEvent" ], [ "string", "kernel.view" ] ] }, { "namespace": "Symfony\\Component\\HttpKernel", "short_class": "HttpKernel", "class": "Symfony\\Component\\HttpKernel\\HttpKernel", "type": "->", "function": "handleRaw", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/http-kernel/HttpKernel.php", "line": 79, "args": [ [ "object", "Symfony\\Component\\HttpFoundation\\Request" ], [ "integer", 1 ] ] }, { "namespace": "Symfony\\Component\\HttpKernel", "short_class": "HttpKernel", "class": "Symfony\\Component\\HttpKernel\\HttpKernel", "type": "->", "function": "handle", "file": "/var/www/html/mws_bundles/mwsuserbundle/vendor/symfony/http-kernel/Kernel.php", "line": 196, "args": [ [ "object", "Symfony\\Component\\HttpFoundation\\Request" ], [ "integer", 1 ], [ "boolean", true ] ] }, { "namespace": "Symfony\\Component\\HttpKernel", "short_class": "Kernel", "class": "Symfony\\Component\\HttpKernel\\Kernel", "type": "->", "function": "handle", "file": "/var/www/html/mws_bundles/mwsuserbundle/public/index.php", "line": 28, "args": [ [ "object", "Symfony\\Component\\HttpFoundation\\Request" ] ] } ] }
How to reproduce
class CustomerAddress
{
...
/**
* @var Address
*/
private $address;
...
}
{
class Address
{
...
/**
* @var string
*/
private $country;
}
<?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="MWS\CustomerBundle\Entity\CustomerAddress"
table="mws_customer_address"
inheritance-type="JOINED"
repository-class="MWS\CustomerBundle\Repository\AddressRepository"
>
...
<embedded name="address" class="Address" />
...
</entity>
</doctrine-mapping>
<class name="MWS\CustomerBundle\Entity\CustomerAddress">
<property name="customer">
<constraint name="NotBlank">
<option name="groups">Address</option>
</constraint>
</property>
<property name="country">
<constraint name="NotBlank">
<option name="groups">Address</option>
</constraint>
<constraint name="Country">
<option name="groups">
<value>Address</value>
</option>
</constraint>
</property>
</class>
Additional context
I tried several other namings for the property country
like address.country
and address_country
but nothing helps.