ManyToOne not updating properly #5426

Closed
opened 2026-01-22 15:07:29 +01:00 by admin · 8 comments
Owner

Originally created by @juniwalk on GitHub (Feb 23, 2017).

Hello,
when I try to remove domain from the Project, it tries to update the $domains collection which is wrong, as it is not the owning side. This happens only when I try to load domains using post-fetching.

$project = $projectRepository->find(1);
$projectRepository->createQueryBuilder('p', 'p.id')
	->select('partial p.{id}, d')
	->leftJoin('p.domains', 'd')
	->where('p = :project')
	->setParameter('project', $project)
	->getQuery()->getResult();

$project->removeDomain(1);
$entityManager->flush();

This fails to do anything. I check the UnitOfWork and it is trying to update $domains collection instead of setting domain.project_id to NULL.

This is not the case if I load $domains in separate query. Then the same removeDomain works as expected. $this->domainRepository->createQueryBuilder('d', 'd.id')->setParameter('project', $project)->where('d.project = :project');

Is this me doing something wrong? Or it that some sort of issue in doctrine?

/**
 * @ORM\Entity(repositoryClass="App\Entity\ProjectRepository")
 */
class Project
{
	/**
	 * @ORM\OneToMany(targetEntity="Domain", mappedBy="project", indexBy="id")
	 * @var Domain[]
	 */
	private $domains;


	/**
	 * @param Domain  $domain
	 */
	public function addDomain(Domain $domain)
	{
		$domain->setProject($this);
		$this->domains->set($domain->getId(), $domain);
	}


	/**
	 * @param  int  $domainId
	 * @return Domain|NULL
	 */
	public function removeDomain(int $domainId)
	{
		if (!$domain = $this->domains->remove($domainId)) {
			return NULL;
		}

		$domain->setProject(NULL);
		return $domain;
	}
}
/**
 * @ORM\Entity(repositoryClass="App\Entity\DomainRepository")
 */
class Domain
{
	/**
	 * @ORM\ManyToOne(targetEntity="Project", inversedBy="domains")
	 * @var Project|NULL
	 */
	private $project;


	/**
	 * @param Project|NULL  $project
	 */
	public function setProject(Project $project = NULL)
	{
		$this->project = $project;
	}
}
Originally created by @juniwalk on GitHub (Feb 23, 2017). Hello, when I try to remove domain from the Project, it tries to update the `$domains` collection which is wrong, as it is not the owning side. This happens only when I try to load domains using post-fetching. ```php $project = $projectRepository->find(1); $projectRepository->createQueryBuilder('p', 'p.id') ->select('partial p.{id}, d') ->leftJoin('p.domains', 'd') ->where('p = :project') ->setParameter('project', $project) ->getQuery()->getResult(); $project->removeDomain(1); $entityManager->flush(); ``` This fails to do anything. I check the UnitOfWork and it is trying to update $domains collection instead of setting `domain.project_id` to `NULL`. This is not the case if I load $domains in separate query. Then the same removeDomain works as expected. `$this->domainRepository->createQueryBuilder('d', 'd.id')->setParameter('project', $project)->where('d.project = :project');` Is this me doing something wrong? Or it that some sort of issue in doctrine? ```php /** * @ORM\Entity(repositoryClass="App\Entity\ProjectRepository") */ class Project { /** * @ORM\OneToMany(targetEntity="Domain", mappedBy="project", indexBy="id") * @var Domain[] */ private $domains; /** * @param Domain $domain */ public function addDomain(Domain $domain) { $domain->setProject($this); $this->domains->set($domain->getId(), $domain); } /** * @param int $domainId * @return Domain|NULL */ public function removeDomain(int $domainId) { if (!$domain = $this->domains->remove($domainId)) { return NULL; } $domain->setProject(NULL); return $domain; } } ``` ```php /** * @ORM\Entity(repositoryClass="App\Entity\DomainRepository") */ class Domain { /** * @ORM\ManyToOne(targetEntity="Project", inversedBy="domains") * @var Project|NULL */ private $project; /** * @param Project|NULL $project */ public function setProject(Project $project = NULL) { $this->project = $project; } } ```
admin added the BugMissing Tests labels 2026-01-22 15:07:29 +01:00
admin closed this issue 2026-01-22 15:07:31 +01:00
Author
Owner

@Ocramius commented on GitHub (Feb 23, 2017):

This fails to do anything. I check the UnitOfWork and it is trying to update $domains collection instead of setting domain.project_id to NULL.

This is really weird. I don't understand the issue, can you please write a test case exposing the desired behavior?

@Ocramius commented on GitHub (Feb 23, 2017): > This fails to do anything. I check the UnitOfWork and it is trying to update $domains collection instead of setting `domain.project_id` to `NULL`. This is really weird. I don't understand the issue, can you please write a test case exposing the desired behavior?
Author
Owner

@juniwalk commented on GitHub (Feb 23, 2017):

@Ocramius Yeah, I will try.

@juniwalk commented on GitHub (Feb 23, 2017): @Ocramius Yeah, I will try.
Author
Owner

@juniwalk commented on GitHub (Feb 24, 2017):

@Ocramius So I was unable to replicate this in a test case so I created simple sandbox.

@juniwalk commented on GitHub (Feb 24, 2017): @Ocramius So I was unable to replicate this in a test case ~~so I created simple sandbox~~.
Author
Owner

@Ocramius commented on GitHub (Mar 24, 2017):

Sorry, but this needs to be a unit test in the suite of this project: nobody is going to debug it inside a larger environment.

@Ocramius commented on GitHub (Mar 24, 2017): Sorry, but this needs to be a unit test in the suite of this project: nobody is going to debug it inside a larger environment.
Author
Owner

@juniwalk commented on GitHub (Apr 26, 2017):

@Ocramius Sorry for the delay, I found another angle on this so I will try to replicate those tests once more.

@juniwalk commented on GitHub (Apr 26, 2017): @Ocramius Sorry for the delay, I found another angle on this so I will try to replicate those tests once more.
Author
Owner

@juniwalk commented on GitHub (Apr 27, 2017):

So I tried again to replicate the issue in the tests to no avail. In the tests it just works as it is supposed to.

I opened up UnitOfWork.php to trace the problem and after few hours I traced the problem to line 2597. If I comment that continue out, it starts working as expected.

// Check if the association is not among the fetch-joined associations already.
if (isset($hints['fetchAlias']) && isset($hints['fetched'][$hints['fetchAlias']][$field])) {
    continue;
}

What shall I do when I am unable to replicate this in tests for you?

@juniwalk commented on GitHub (Apr 27, 2017): So I tried again to replicate the issue in the tests to no avail. In the tests it just works as it is supposed to. I opened up [UnitOfWork.php](https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L2597) to trace the problem and after few hours I traced the problem to [line 2597](https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L2597). If I comment that continue out, it starts working as expected. ```php // Check if the association is not among the fetch-joined associations already. if (isset($hints['fetchAlias']) && isset($hints['fetched'][$hints['fetchAlias']][$field])) { continue; } ``` What shall I do when I am unable to replicate this in tests for you?
Author
Owner

@Ocramius commented on GitHub (May 2, 2017):

@juniwalk without a test case reproducing this, no development can be done around it, sorry :-(

@Ocramius commented on GitHub (May 2, 2017): @juniwalk without a test case reproducing this, no development can be done around it, sorry :-(
Author
Owner

@juniwalk commented on GitHub (Feb 26, 2021):

Issue was on my side.

@juniwalk commented on GitHub (Feb 26, 2021): Issue was on my side.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5426