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

EntityManager::getReference() should handle a PK which is also a FK #11601

Open
wants to merge 8 commits into
base: 2.20.x
Choose a base branch
from

Conversation

le-yak
Copy link

@le-yak le-yak commented Sep 17, 2024

EntityManager::getReference() should be able to handle a PK which is also a FK, just the way ::find() already does.

class Entity
{
  #[Id]
  #[ManyToOne(targetEntity: Related::class)]
  public Related $related
}

Current behaviour:

// case 1: by PK value
$entityManager->getReference(Entity::class, 1);
// Cannot assign int to property Entity::$related of type Related
// case 2: by reference
$related = $entityManager->getReference(Related::class, 1]);
$entityManager->getReference(Entity::class, $related);
// Object of class Related could not be converted to string

With this PR, the proxy factory would hydrate the proxy with a reference to the related entity if a relation is detected (addressing case 1 above)
Additionally EntityManager::getReference() would use the same approach as in find() and attempt to extract the underlying PK value when passed an entity (case 2).

In this first attempt, I just copy/pasted some code from find() to getReference(). These two have a lot in common, if this proposed change is of any interest I will improve it and deduplicate this code in a second version.

P.S. I believe this (somewhat related) issue #5640 may be closed.

@greg0ire
Copy link
Member

greg0ire commented Sep 17, 2024

It seems there are CI jobs failing. Please take a look at this guide for more on how to handle those.

@greg0ire greg0ire added the Bug label Sep 17, 2024
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.

if this proposed change is of any interest I will improve it and deduplicate this code in a second version.

I see no reason to reject your change, so I'd say please go ahead and deduplicate this.

@greg0ire
Copy link
Member

If this also affects 2.x, please retarget.

@le-yak le-yak force-pushed the feat/get-reference-where-pk-is-fk branch from d29511b to 9dbc430 Compare September 17, 2024 20:42
@le-yak le-yak marked this pull request as draft September 20, 2024 11:50
@SenseException
Copy link
Member

Does this need to be a draft? It looks like it's reviewable to me as a regular PR. Or is this still a WIP?

@le-yak le-yak force-pushed the feat/get-reference-where-pk-is-fk branch from 9dbc430 to b2e4500 Compare September 22, 2024 23:23
@le-yak le-yak changed the base branch from 3.2.x to 2.20.x September 22, 2024 23:23
@le-yak
Copy link
Author

le-yak commented Sep 22, 2024

Yes, I am still working on it. I duplicated some code for the proof of concept, this needs refactoring. In the meantime, I discovered that error cases also need to be addressed (tests marked as skipped with "work in progress").

Additionally, I discovered that updating the identifier of a proxy fails silently. This is pre-existing behaviour, but the change I propose introduces a whole class of scenarios (tests skipped with "use case needs to be confirmed") that I think should be addressed. I wanted to open a discussion about it, please let me know if I should open another issue instead.

Notice that all skipped tests pass if one replaces getReference() with find().

For information, I probably won't be able to work on it much before next week-end.

@le-yak
Copy link
Author

le-yak commented Oct 5, 2024

Apologies for the delay, I've been quite busy lately. I should be able to submit a final proposal by the end of the weekend.

@le-yak le-yak force-pushed the feat/get-reference-where-pk-is-fk branch from b2e4500 to 6ae5153 Compare October 6, 2024 20:51
@le-yak
Copy link
Author

le-yak commented Oct 6, 2024

I'm afraid I am unable to address either case:

  1. attempting to access properties of a "broken" proxy (i.e. with an invalid, non-existing identifier) results in an obscure runtime error (Undefined array key "primary key column name") whereas a EntityNotFoundException would be in order. This only affects entities with relations in the identifier (i.e. those for which a proxy could not be created previously).
  2. updating the identifier of a proxy fails silently. This already affected regular identifiers, and it now also affects identifier with relations.

I am not sure as how to move forward, please advise:

  • is the incomplete fix acceptable as is? If so, should I just delete the skipped test cases?
  • perhaps someone more capable should pick up from here?

@le-yak le-yak marked this pull request as ready for review October 6, 2024 22:11
@le-yak le-yak marked this pull request as draft October 8, 2024 11:53
@le-yak le-yak force-pushed the feat/get-reference-where-pk-is-fk branch from 5c7ced1 to be06aa9 Compare October 8, 2024 21:16
Comment on lines +58 to +66
if ($this->_em->getConfiguration()->isLazyGhostObjectEnabled()) {
self::assertInstanceOf(UserProxy::class, $profile->user);
self::assertEquals('Athos', $profile->user->name);
} else {
if (PHP_VERSION_ID >= 80100) {
$this->markTestIncomplete();
}
self::assertEquals(1, $profile->user);
}
Copy link
Author

Choose a reason for hiding this comment

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

I figured out that Proxies behave slightly differently when "Lazy Ghost Objects" are not enabled. Through experimentation I reached the conclusion that only PHP < 8.1 appears to be displaying the legacy behaviour. This deprecation notice seems to confirm my hypothesis.

@le-yak
Copy link
Author

le-yak commented Oct 8, 2024

I now realize I quite grossly underestimated the beast. I will not be able, nor willing, to dig deeper into this.

@le-yak le-yak marked this pull request as ready for review October 8, 2024 22:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants