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

ValidatorException on Doctrine Proxy (Auto Validation Mapping?) #31715

Closed
fabstei opened this issue May 30, 2019 · 28 comments
Closed

ValidatorException on Doctrine Proxy (Auto Validation Mapping?) #31715

fabstei opened this issue May 30, 2019 · 28 comments

Comments

@fabstei
Copy link
Contributor

fabstei commented May 30, 2019

Symfony version(s) affected:
4.3 (Beta2 & RC1)

Description
Handling a request with a form that has an assigned Entity seems to wrongly trigger a ValidatorException.

How to reproduce
My apologies for the missing reproducer - I'm having issues creating it. since 4.3.0-RC1 is affected I thought sharing even without one could help.

        $entityManager = $this->getDoctrine()->getManager();
        $person = $entityManager->getRepository(Person::class)->findOneBy(['id' => $id]);

        $form = $this->createForm(PersonType::class, $person);
        $form->handleRequest($request);

triggers

ValidatorException: Property "xyz" does not exist in class "Proxies\__CG__\App\Entity\Person"

in PropertyMetadata.php#L39-L41

The stacktrace is here: https://gist.github.com/fabstei/ee254c7945ebc79fd3fed75cf4de82db

Possible Solution
None so far. After uncommenting PropertyMetadata.php#L39-L41 everything works as expected, but it's obviously not a solution.

Additional context

  • Mac OS Mojave 10.14.5
  • PHP 7.3.5
@ThomasTr
Copy link
Contributor

Same for me, recently upgraded to 4.3.0, form with a EntityType, for now on, the properties of these entity must be public to avoid this exception?!?

@xabbuh
Copy link
Member

xabbuh commented May 30, 2019

Did you enable the new auto_mapping feature (see #27735) or does it also happen without doing so?

@pbowyer
Copy link
Contributor

pbowyer commented May 30, 2019

It happens without enabling auto_mapping. For my project it's been a straight switch of 4.2.* to 4.3.* in composer.json; only other changes are to clean up deprecations with the Workflow component.

@ThomasTr
Copy link
Contributor

For me, auto_mapping was already enabled without any issues prior to 4.3.0

@pbowyer
Copy link
Contributor

pbowyer commented May 30, 2019

Did you enable the new auto_mapping feature

I can't find any docs on how this new feature is enabled/disabled; the only auto_mapping I find is in doctrine.yaml which in my project is:

doctrine:
    # dbal stuff here
    orm:
        auto_generate_proxy_classes: true
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                type: annotation
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'App\Entity'
                alias: App

This was auto-generated when first creating the project using Symfony 4.2.2.

@xabbuh
Copy link
Member

xabbuh commented May 30, 2019

I mean the new framework.validation.auto_mapping option (see https://github.com/symfony/symfony/blob/4.3/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php#L850).

@pbowyer
Copy link
Contributor

pbowyer commented May 30, 2019

I have not set it, and it isn't present in the config files (my framework.yaml doesn't have a validation key).

Running bin/console debug:config framework gives:

framework:
    # ...
    validation:
        email_validation_mode: html5
        enabled: true
        enable_annotations: true
        static_method:
            - loadValidatorMetadata
        translation_domain: validators
        mapping:
            paths: {  }
        not_compromised_password:
            enabled: true
            endpoint: null
        auto_mapping: {  }

@xabbuh
Copy link
Member

xabbuh commented May 30, 2019

#31749 is a first steps which at least ensures that auto mapping is not enabled by default. Though that doesn't fix the core issue with Doctrine proxies.

nicolas-grekas added a commit that referenced this issue May 31, 2019
…apping by default (xabbuh)

This PR was merged into the 4.3 branch.

Discussion
----------

[DoctrineBridge][Validator] do not enable validator auto mapping by default

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | part of #31715, #31752
| License       | MIT
| Doc PR        |

Commits
-------

a3555fc do not enable validator auto mapping by default
@MortalFlesh
Copy link

Hello,

it seems I have this exception as well. But with embedded doctrine entity.

I have Embeddable entity Foo with fields one and two. And the entity Bar, which has Foo embeded like this Embedded(class="Foo", columnPrefix=false). And I get the error of Property "foo.one" does not exist in class "Bar".

I think it is because of autovalidating a length of column, since both one and two are defined like this

// Foo
/**
 * @ORM\Column(type="string", length=100)
 *
 * @var string
 */
private $one;

@fabstei
Copy link
Contributor Author

fabstei commented May 31, 2019

@MortalFlesh it seems that Nicolas Grekas is already on it - in the meantime try setting this in your framework config:

framework:
    validation:
        auto_mapping: {}

@guillaumesmo
Copy link
Contributor

guillaumesmo commented May 31, 2019

@fabstei @MortalFlesh I have the same issue with embedded entities in a Symfony 4.3 migration

Unfortunately, using auto_mapping: {} doesn't seem to help, DoctrineLoader is still called and the exception is thrown

The auto_mapper is always being registered by the doctrine-bundle, not sure how the auto_mapping param affects the registration:
https://github.com/doctrine/DoctrineBundle/blob/master/DependencyInjection/DoctrineExtension.php#L811

EDIT: this works for me: auto_mapping: {'App\\': {}}

@IMSDeveloper
Copy link

I'm also seeing this error in Symfony 4.3.0. The property it's complaining about is definitely in the entity. The property is defined as '@Orm\Column(type="string", length=100, nullable=true, unique=true)'

Same as above, settings the auto_mapping property does not resolve this. I'm also seeing a similar issue with inherited entities i.e. I have an entity class extending another - it's unable to access properties of the base class.

@ayalon
Copy link

ayalon commented Jun 3, 2019

I have the same issue with the following field definition:

    /**
     *
     * The id
     *
     * @var string
     *
     * @ORM\Column(name="my_id", type="string", length=60, nullable=true)
     */
    private $my_id;

@xabbuh
Copy link
Member

xabbuh commented Jun 3, 2019

Can one of you create an example application that allows to reproduce?

@pulsesalessolutions
Copy link

pulsesalessolutions commented Jun 3, 2019

@guillaumesmo,

Thanks that seems to have worked for me;

framework.yaml

framework: validation: auto_mapping: {'App\\': {}}

@IMSDeveloper
Copy link

@pulsesalessolutions This works for me also!

@rjwebdev
Copy link
Contributor

rjwebdev commented Jun 4, 2019

Facing same issue after submitting a form. Mapping on my entity:

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $street;

Error I get after submitting the form:
[2019-06-03 23:44:29] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Validator\Exception\ValidatorException: "Property "street" does not exist in class "Proxies\__CG__\App\Entity\Core\Address"" at /vendor/symfony/validator/Mapping/PropertyMetadata.php line 40 {"exception":"[object] (Symfony\\Component\\Validator\\Exception\\ValidatorException(code: 0): Property \"street\" does not exist in class \"Proxies\\__CG__\\App\\Entity\\Core\\Address\" at /vendor/symfony/validator/Mapping/PropertyMetadata.php:40)"} []

@Flinsch
Copy link
Contributor

Flinsch commented Jun 4, 2019

@guillaumesmo's solution works for me too:

framework: validation: auto_mapping: {'App\\': {}}

I have some Doctrine entities with inheritance, and in forms for derived entities I got this "property does not exist" problem for properties of base classes since 4.3, as already described by others. I don't know how and why, but auto_mapping set to {'App\\': {}} works. It seems that the documentation is quite behind the actual release, at least I can't find anything about this auto_mapping feature, as @pbowyer mentioned before. The documentation inconsistencies also apply for (all?) other aspects/features of 4.3: on the docs pages, the version is set to 4.3, but the content doesn't address the changes listed at UPGRADE-4.3md.

@christian-kolb
Copy link

This also affects third party bundles like gesdinet/jwt-refresh-token-bundle: markitosgv/JWTRefreshTokenBundle#151
They plan to wait until it's resolved in the related symfony component. Is this expectable?

@xabbuh
Copy link
Member

xabbuh commented Jun 4, 2019

Can you check if #31836 finally solves this issue?

@fabpot fabpot closed this as completed Jun 4, 2019
fabpot added a commit that referenced this issue Jun 4, 2019
…rent class (xabbuh)

This PR was merged into the 4.3 branch.

Discussion
----------

[DoctrineBridge] do not process private properties from parent class

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #31715, #31752
| License       | MIT
| Doc PR        |

Commits
-------

adfa1ef do not process private properties from parent class
@guillaumesmo
Copy link
Contributor

guillaumesmo commented Jun 4, 2019

@xabbuh that fixed the problem indeed, no need to the auto_mapping param anymore

Thank you

@xabbuh
Copy link
Member

xabbuh commented Jun 4, 2019

@guillaumesmo Thank you very much for the feedback.

@teohhanhui
Copy link
Contributor

I'm not sure that this issue is actually fixed. The problem in the first place was that Doctrine's proxy class was being used instead of the actual entity class. The related PRs don't seem to address that problem, but merely avoiding it.

@xabbuh
Copy link
Member

xabbuh commented Jun 5, 2019

@teohhanhui If I don't miss anything, the issue was that the DoctrineLoader tried to add constraints to the Doctrine proxy classes that had already been attached to the actual entity class before.

@teohhanhui
Copy link
Contributor

teohhanhui commented Jun 5, 2019

It was registering DoctrineLoader with no regexp: https://github.com/doctrine/DoctrineBundle/blob/a8377d4b60b931a3ad28712aa80fe0b6e3b7c9db/DependencyInjection/DoctrineExtension.php#L799-L812

But I thought a Doctrine proxy class would fail this check:

try {
$doctrineMetadata = $this->entityManager->getClassMetadata($className);
} catch (MappingException | OrmMappingException $exception) {
return false;
}

@xabbuh
Copy link
Member

xabbuh commented Jun 5, 2019

The fact that the feature was enabled by default was another bug fixed in #31749.

@teohhanhui
Copy link
Contributor

@xabbuh I know, but what I was trying to say is that, the bug shouldn't exist according to my logic above, but it does. Which means that my understanding was wrong, which means that we didn't get to the root of the problem, and maybe the bug is still not fixed...

@xabbuh
Copy link
Member

xabbuh commented Jun 5, 2019

I think I do not really understand the issue then. Could you create a small example application that allows to reproduce this?

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

No branches or pull requests