diff --git a/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php index 0e06e889df7..b008e63ebaa 100644 --- a/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php @@ -249,7 +249,7 @@ public function loadCriteria(PersistentCollection $collection, Criteria $criteri $field = $this->quoteStrategy->getColumnName($name, $targetClass, $this->platform); $whereClauses[] = sprintf('te.%s %s ?', $field, $operator); $params[] = $value; - $paramTypes[] = PersisterHelper::getTypeOfColumn($field, $targetClass, $this->em); + $paramTypes[] = PersisterHelper::getTypeOfField($name, $targetClass, $this->em)[0]; } $tableName = $this->quoteStrategy->getTableName($targetClass, $this->platform); diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9109Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9109Test.php new file mode 100644 index 00000000000..97d5da842b2 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9109Test.php @@ -0,0 +1,217 @@ +_schemaTool->createSchema( + [ + $this->_em->getClassMetadata(GH9109User::class), + $this->_em->getClassMetadata(GH9109Product::class), + ] + ); + } + + protected function tearDown(): void + { + $this->_schemaTool->dropSchema( + [ + $this->_em->getClassMetadata(GH9109User::class), + $this->_em->getClassMetadata(GH9109Product::class), + ] + ); + + parent::tearDown(); + } + + public function testIssue(): void + { + $userFirstName = 'GH9109Test'; + $userLastName = 'UserGH9109'; + $productTitle = 'Test product'; + + $userRepository = $this->_em->getRepository(GH9109User::class); + + $user = new GH9109User(); + $user->setFirstName($userFirstName); + $user->setLastName($userLastName); + + $product = new GH9109Product(); + $product->setTitle($productTitle); + + $this->_em->persist($user); + $this->_em->persist($product); + $this->_em->flush(); + + $product->addBuyer($user); + + $this->_em->persist($product); + $this->_em->flush(); + + $this->_em->clear(); + + $persistedProduct = $this->_em->find(GH9109Product::class, $product->getId()); + + // assert Product was persisted + self::assertInstanceOf(GH9109Product::class, $persistedProduct); + self::assertEquals($productTitle, $persistedProduct->getTitle()); + + // assert Product has a Buyer + $count = $persistedProduct->getBuyers()->count(); + self::assertEquals(1, $count); + + // assert NOT QUOTED will WORK with findOneBy + $user = $userRepository->findOneBy(['lastName' => $userLastName]); + self::assertInstanceOf(GH9109User::class, $user); + self::assertEquals($userLastName, $user->getLastName()); + + // assert NOT QUOTED will WORK with Criteria + $criteria = Criteria::create(); + $criteria->where($criteria->expr()->eq('lastName', $userLastName)); + $user = $persistedProduct->getBuyers()->matching($criteria)->first(); + self::assertInstanceOf(GH9109User::class, $user); + self::assertEquals($userLastName, $user->getLastName()); + + // assert QUOTED will WORK with findOneBy + $user = $userRepository->findOneBy(['firstName' => $userFirstName]); + self::assertInstanceOf(GH9109User::class, $user); + self::assertEquals($userFirstName, $user->getFirstName()); + + // assert QUOTED will WORK with Criteria + $criteria = Criteria::create(); + $criteria->where($criteria->expr()->eq('firstName', $userFirstName)); + $user = $persistedProduct->getBuyers()->matching($criteria)->first(); + self::assertInstanceOf(GH9109User::class, $user); + self::assertEquals($userFirstName, $user->getFirstName()); + } +} + +/** + * @Entity + */ +class GH9109Product +{ + /** + * @var int $id + * @Column(name="`id`", type="integer") + * @Id + * @GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @var string $title + * @Column(name="`title`", type="string", length=255) + */ + private $title; + + /** + * @var Collection|GH9109User[] + * @psalm-var Collection + * @ManyToMany(targetEntity="GH9109User") + */ + private $buyers; + + public function __construct() + { + $this->buyers = new ArrayCollection(); + } + + public function getId(): int + { + return $this->id; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } + + public function getTitle(): string + { + return $this->title; + } + + /** + * @psalm-return Collection + */ + public function getBuyers(): Collection + { + return $this->buyers; + } + + public function addBuyer(GH9109User $buyer): void + { + $this->buyers[] = $buyer; + } +} + +/** + * @Entity + */ +class GH9109User +{ + /** + * @var int + * @Column(name="`id`", type="integer") + * @Id + * @GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @var string + * @Column(name="`first_name`", type="string") + */ + private $firstName; + + /** + * @var string + * @Column(name="last_name", type="string") + */ + private $lastName; + + public function getId(): int + { + return $this->id; + } + + public function getFirstName(): string + { + return $this->firstName; + } + + public function setFirstName(string $firstName): void + { + $this->firstName = $firstName; + } + + public function getLastName(): string + { + return $this->lastName; + } + + public function setLastName(string $lastName): void + { + $this->lastName = $lastName; + } +}