Skip to content

Fix incorrect instance of ReflectionProperty created for public typed properties#103

Merged
greg0ire merged 1 commit intodoctrine:2.2.xfrom
joaojacome:fix-typed-properties
Jun 15, 2021
Merged

Fix incorrect instance of ReflectionProperty created for public typed properties#103
greg0ire merged 1 commit intodoctrine:2.2.xfrom
joaojacome:fix-typed-properties

Conversation

@joaojacome
Copy link
Contributor

@joaojacome joaojacome commented Apr 3, 2020

Resolves #102

@joaojacome joaojacome changed the base branch from master to 1.3.x April 3, 2020 16:40
@SenseException
Copy link
Member

Thanks for your contribution. Your switch in the if-block is supposed to fix an issue with the created ReflectionProperty instance. Can you please create a test that covers this issue and prevents regression in this project?

@joaojacome
Copy link
Contributor Author

I've added the tests for this issue. Can you check again, please?

self::assertNotInstanceOf(TypedNoDefaultReflectionProperty::class, $reflProp);
}

public function testGetTypedPublicNoDefaultPropertyWorksWithGetValue() : void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test got changed by your PR. If the old test using RuntimePublicReflectionProperty would fail with your changes, you might have implemented a BC-break here and 1.3.x wouldn't be the appropriate target branch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old test fails with the fix - but wouldn't the old behaviour be considered a bug?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bugfix that introduces BC break could only be merged into a major release. The fix should also be reviewed by other maintainers too.

Copy link
Contributor

@guilliamxavier guilliamxavier Jun 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix has been hold off for too long... as it is we might not even have it for version 3.0... Wouldn't it be possible to preserve BC? e.g. use a new class that extends RuntimePublicReflectionProperty but uses the same code as TypedNoDefaultReflectionProperty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. To avoid code duplication, I've added a trait to hold the common methods, although I'm not sure if it's the best approach.

The test now covers the old and the new behaviours.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well my question was primarily to @SenseException (and other maintainers), but I was thinking to something like that yes 🙂 Thanks, now let's wait for new reviews 😉

@oalphenaar
Copy link

Will this be merged? As of today it is still impossible to remove entities where the id property is public and this seems to be the fix.

@malarzm
Copy link
Member

malarzm commented Dec 31, 2020

There's #103 (comment) that needs to be checked/addressed

@joaojacome joaojacome marked this pull request as draft May 11, 2021 18:19
@joaojacome joaojacome changed the base branch from 1.3.x to 2.2.x June 8, 2021 16:09
@joaojacome joaojacome force-pushed the fix-typed-properties branch from ffc3e12 to 2b3a92c Compare June 8, 2021 16:20
@joaojacome joaojacome marked this pull request as ready for review June 8, 2021 16:24
@greg0ire
Copy link
Member

greg0ire commented Jun 9, 2021

Please associate your email address with your Github account, or change the
email in your commits to an address already associated with it. If you do not
want to expose your personal email address, you may use
$userName@users.noreply.github.com, that way we can still reach you through Github.
Additionally, you will get credit for this contribution on your Github profile.

SenseException
SenseException previously approved these changes Jun 14, 2021
@SenseException SenseException requested a review from greg0ire June 14, 2021 21:06
@greg0ire
Copy link
Member

greg0ire commented Jun 14, 2021

My review has been requested. Before I review this, I obviously have to read #102, which mentions an incorrect type but does not explain what makes it incorrect, and refers me to doctrine/orm#7999.
doctrine/orm#7999 is a lengthy issue with 17 replies, a wall of text and 11 participants. It mentions doctrine/orm#7940 a pull request with 35 replies, which fixes doctrine/orm#7864, which is another wall of text.

I might find the time and energy to review this one day, but today is not that day, sorry.

If you want to speed things up, please squash your commits into one, and improve your commit message according to the contributing guide. It would be great if it mentioned the reason you are doing this, #103 (comment) , what changes you made and why they fix the issue.

@guilliamxavier
Copy link
Contributor

@greg0ire: I can at least recap what led me here: The original issue is indeed doctrine/orm#7999: you get a TypeError (from deep in Doctrine's internals) when you try to delete an entity with a generated id on a non-nullable typed property. E.g.:

/** @ORM\Entity */
class MyEntity {
    /** @ORM\Id @ORM\GeneratedValue @ORM\Column(type="integer") */
    public int $id;
}

$myEntity = $entityManager->find(MyEntity::class, 42); // let's assume it exists

$entityManager->remove($myEntity);
$entityManager->flush(); // Typed property Entity::$id must be int, null used

(because Doctrine tries to "reset" the id to null).

Then doctrine/reflection#35 fixed it but only for private/protected properties, not public (maybe because #94 thought that "RuntimePublicReflectionProperty already works with typed no default properties", only considering lazy loading at that time).

Now this PR aims to fix it also for public properties (note: the first fix was simply to reverse the order, resulting in what was initially proposed in #90, but since eventually #94 chose the "wrong" order, there was some BC-change requested).

(As for the EXTRA_LAZY issue, it actually seems unrelated.)

But indeed, there is place for improvement of the commit message (@joaojacome 😉)

@greg0ire
Copy link
Member

Thanks, I will try to look at this today, it looks a bit more approachable now :)

@alcaeus alcaeus self-requested a review June 15, 2021 08:53
alcaeus
alcaeus previously approved these changes Jun 15, 2021
Copy link
Member

@alcaeus alcaeus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit in tests, but LGTM.

@joaojacome
Copy link
Contributor Author

joaojacome commented Jun 15, 2021

@greg0ire:
But indeed, there is place for improvement of the commit message (@joaojacome wink)

I'll squash it and give it a proper message :)

@joaojacome joaojacome dismissed stale reviews from alcaeus and SenseException via 30bd166 June 15, 2021 14:45
… untyped ones

Due to how PHP 7.4 works, if you have a typed public property that does not support null values, whenever Doctrine tries to delete an entity with such properties,
it raises a TypeError. This happens because of the new default "uninitialized" value for typed properties. In previous versions of PHP, the default uninitialized value was null.

My fist idea was to just reverse the order, and while that worked, it introduced a BC break.
Now, as per @guilliamxavier suggestion, I've moved the methods from the class TypedNoDefaultRuntimePublicReflectionProperty to
a trait, then I proceeded to create a new class extending RuntimePublicReflectionProperty, that uses the new trait.

With this, whenever Doctrine tries to access a public property with no default value set, it will properly unset the property instead of setting it as null getting a PHP TypeError.
Reordered property type resolution so typed properties get resolved first, added tests for covering multiple scenarios

Fixes doctrine#102
Fixes doctrine/orm#7999

Co-authored-by: Guilliam Xavier <guilliamxavier@users.noreply.github.com>
@joaojacome joaojacome force-pushed the fix-typed-properties branch from 58eb227 to dc3d9eb Compare June 15, 2021 14:54
Copy link
Member

@greg0ire greg0ire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that's a commit message! It feels a lot safer to merge this, thanks a lot!

@greg0ire greg0ire added the Bug Something isn't working label Jun 15, 2021
@greg0ire greg0ire added this to the 2.2.2 milestone Jun 15, 2021
@greg0ire greg0ire merged commit 27d6134 into doctrine:2.2.x Jun 15, 2021
@greg0ire
Copy link
Member

Thanks everyone!

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

Labels

Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect instance of ReflectionProperty created for public typed properties

7 participants