findBy does not accept array anymore #6311

Closed
opened 2026-01-22 15:30:36 +01:00 by admin · 7 comments
Owner

Originally created by @JKoty on GitHub (Sep 26, 2019).

Originally assigned to: @JKoty on GitHub.

Bug Report

Q A
BC Break yes
Version 2.6.4

Summary

Using findBy with array generated SQL relatedEntity.id IN (Related\Entity\Full\Namespace(<id>), Related\Entity\Full\Namespace(<id2>)) instead of just relatedEntity.id IN (<id>, <id2>)

Current behavior

$arrayOfEntity = [$entity1, $entity2];
$result = $repository->findBy(['relatedEntity' => $arrayOfEntity])
// $result is empty though in version 2.6.3 it was not

How to reproduce

see above

Expected behavior

result contains related entity

Originally created by @JKoty on GitHub (Sep 26, 2019). Originally assigned to: @JKoty on GitHub. ### Bug Report | Q | A |------------ | ------ | BC Break | yes | Version | 2.6.4 #### Summary Using `findBy` with array generated SQL `relatedEntity.id IN (Related\Entity\Full\Namespace(<id>), Related\Entity\Full\Namespace(<id2>))` instead of just `relatedEntity.id IN (<id>, <id2>)` #### Current behavior ``` $arrayOfEntity = [$entity1, $entity2]; $result = $repository->findBy(['relatedEntity' => $arrayOfEntity]) // $result is empty though in version 2.6.3 it was not ``` #### How to reproduce see above #### Expected behavior result contains related entity
admin added the BugMissing Tests labels 2026-01-22 15:30:36 +01:00
admin closed this issue 2026-01-22 15:30:36 +01:00
Author
Owner

@jaikdean commented on GitHub (Sep 26, 2019):

Possibly related to #7830

@jaikdean commented on GitHub (Sep 26, 2019): Possibly related to #7830
Author
Owner

@SenseException commented on GitHub (Sep 29, 2019):

Let's keep this issue open until it is sure that there is a relation to the mentioned bug.

@SenseException commented on GitHub (Sep 29, 2019): Let's keep this issue open until it is sure that there is a relation to the mentioned bug.
Author
Owner

@lcobucci commented on GitHub (Oct 1, 2019):

@JKoty I've tried to reproduce this issue in a functional test but failed miserably. Would please take a look at the sample test case to see what I've missed and send us PR with a failing test?

Sample test case
<?php
declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\Tests\OrmFunctionalTestCase;

/**
 * @group GH7835
 */
final class GH7835Test extends OrmFunctionalTestCase
{
    protected function setUp() : void
    {
        parent::setUp();

        $this->setUpEntitySchema([GH7835Item::class]);
    }

    /**
     * @test
     */
    public function findByCanReceiveArrayOfObjectsAsFilter(): void
    {
        $parent1 = new GH7835Item(1, 'Test 1');
        $parent2 = new GH7835Item(2, 'Test 2');

        $this->_em->persist($parent1);
        $this->_em->persist($parent2);
        $this->_em->persist(new GH7835Item(3, 'Test 3', $parent1));
        $this->_em->persist(new GH7835Item(4, 'Test 4', $parent1));
        $this->_em->persist(new GH7835Item(5, 'Test 5', $parent2));
        $this->_em->flush();

        $items = $this->_em->getRepository(GH7835Item::class)->findBy(['parent' => [$parent1, $parent2]]);

        self::assertCount(3, $items);
    }
}

/** @Entity */
class GH7835Item
{
    /**
     * @Id()
     * @Column(type="integer")
     *
     * @var int
     */
    public $id;

    /**
     * @Column
     *
     * @var string
     */
    public $name;

    /**
     * @ManyToOne(targetEntity=GH7835Item::class)
     *
     * @var GH7835Item|null
     */
    public $parent;

    public function __construct(int $id, string $name, ?GH7835Item $parent = null)
    {
        $this->id = $id;
        $this->name = $name;
        $this->parent = $parent;
    }
}
@lcobucci commented on GitHub (Oct 1, 2019): @JKoty I've tried to reproduce this issue in a functional test but failed miserably. Would please take a look at the sample test case to see what I've missed and send us PR with a failing test? <details> <summary>Sample test case</summary> ```php <?php declare(strict_types=1); namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\Tests\OrmFunctionalTestCase; /** * @group GH7835 */ final class GH7835Test extends OrmFunctionalTestCase { protected function setUp() : void { parent::setUp(); $this->setUpEntitySchema([GH7835Item::class]); } /** * @test */ public function findByCanReceiveArrayOfObjectsAsFilter(): void { $parent1 = new GH7835Item(1, 'Test 1'); $parent2 = new GH7835Item(2, 'Test 2'); $this->_em->persist($parent1); $this->_em->persist($parent2); $this->_em->persist(new GH7835Item(3, 'Test 3', $parent1)); $this->_em->persist(new GH7835Item(4, 'Test 4', $parent1)); $this->_em->persist(new GH7835Item(5, 'Test 5', $parent2)); $this->_em->flush(); $items = $this->_em->getRepository(GH7835Item::class)->findBy(['parent' => [$parent1, $parent2]]); self::assertCount(3, $items); } } /** @Entity */ class GH7835Item { /** * @Id() * @Column(type="integer") * * @var int */ public $id; /** * @Column * * @var string */ public $name; /** * @ManyToOne(targetEntity=GH7835Item::class) * * @var GH7835Item|null */ public $parent; public function __construct(int $id, string $name, ?GH7835Item $parent = null) { $this->id = $id; $this->name = $name; $this->parent = $parent; } } ``` </details>
Author
Owner

@JKoty commented on GitHub (Oct 2, 2019):

@lcobucci

Here you have.

Failing test case

<?php
declare(strict_types=1);
namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ParameterType;
use Doctrine\ORM\Annotation as ORM;
use Doctrine\Tests\OrmFunctionalTestCase;


final class GH7835Test extends OrmFunctionalTestCase
{
	protected function setUp(): void
	{
		parent::setUp();

		$this->setUpEntitySchema([GH7835Item::class]);
	}

	/**
	 * @test
	 */
	public function findByCanReceiveArrayOfObjectsAsFilter(): void
	{
		$parent1 = new GH7835Item(1, 'Test 1');
		$parent2 = new GH7835Item(2, 'Test 2');

		$this->em->persist($parent1);
		$this->em->persist($parent2);
		$this->em->persist(new GH7835Item(3, 'Test 3', $parent1));
		$this->em->persist(new GH7835Item(4, 'Test 4', $parent1));
		$this->em->persist(new GH7835Item(5, 'Test 5', $parent2));
		$this->em->flush();

		$items = $this->em->getRepository(GH7835Item::class)->createQueryBuilder('it');
		$items->andWhere('it.parent IN (:parents)')->setParameter('parents', [$parent1, $parent2]);
		self::assertCount(3, $items->getQuery()->getResult()); // this works in both versions

		$items2 = $this->em->getRepository(GH7835Item::class)->createQueryBuilder('it2');
		$type = ParameterType::STRING + Connection::ARRAY_PARAM_OFFSET;
		$items2->andWhere('it2.parent IN (:parents)')->setParameter('parents', [$parent1, $parent2], $type);
		self::assertCount(3, $items2->getQuery()->getResult()); // this works only in 2.6.3

	}
}

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

	/**
	 * @ORM\Column
	 *
	 * @var string
	 */
	public $name;

	/**
	 * @ORM\ManyToOne(targetEntity=GH7835Item::class)
	 *
	 * @var GH7835Item|null
	 */
	public $parent;

	public function __construct(int $id, string $name, ?GH7835Item $parent = null)
	{
		$this->id = $id;
		$this->name = $name;
		$this->parent = $parent;
	}


	public function __toString()
	{
		return 'object with id ' . $this->id;
	}
}

I have to correct myself, it's not really in findBy. I had facade over it which I did not notice. But I have done some digging and found out its in $type parameter of ->setParameter() method. So it is probably same issue as in #7830
I also had to add __toString method to entity.

@JKoty commented on GitHub (Oct 2, 2019): @lcobucci Here you have. <details> <summary>Failing test case</summary> ``` <?php declare(strict_types=1); namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\DBAL\Connection; use Doctrine\DBAL\ParameterType; use Doctrine\ORM\Annotation as ORM; use Doctrine\Tests\OrmFunctionalTestCase; final class GH7835Test extends OrmFunctionalTestCase { protected function setUp(): void { parent::setUp(); $this->setUpEntitySchema([GH7835Item::class]); } /** * @test */ public function findByCanReceiveArrayOfObjectsAsFilter(): void { $parent1 = new GH7835Item(1, 'Test 1'); $parent2 = new GH7835Item(2, 'Test 2'); $this->em->persist($parent1); $this->em->persist($parent2); $this->em->persist(new GH7835Item(3, 'Test 3', $parent1)); $this->em->persist(new GH7835Item(4, 'Test 4', $parent1)); $this->em->persist(new GH7835Item(5, 'Test 5', $parent2)); $this->em->flush(); $items = $this->em->getRepository(GH7835Item::class)->createQueryBuilder('it'); $items->andWhere('it.parent IN (:parents)')->setParameter('parents', [$parent1, $parent2]); self::assertCount(3, $items->getQuery()->getResult()); // this works in both versions $items2 = $this->em->getRepository(GH7835Item::class)->createQueryBuilder('it2'); $type = ParameterType::STRING + Connection::ARRAY_PARAM_OFFSET; $items2->andWhere('it2.parent IN (:parents)')->setParameter('parents', [$parent1, $parent2], $type); self::assertCount(3, $items2->getQuery()->getResult()); // this works only in 2.6.3 } } /** @ORM\Entity() */ class GH7835Item { /** * @ORM\Id() * @ORM\Column(type="integer") * * @var int */ public $id; /** * @ORM\Column * * @var string */ public $name; /** * @ORM\ManyToOne(targetEntity=GH7835Item::class) * * @var GH7835Item|null */ public $parent; public function __construct(int $id, string $name, ?GH7835Item $parent = null) { $this->id = $id; $this->name = $name; $this->parent = $parent; } public function __toString() { return 'object with id ' . $this->id; } } ``` </details> I have to correct myself, it's not really in findBy. I had facade over it which I did not notice. But I have done some digging and found out its in `$type` parameter of `->setParameter()` method. So it is probably same issue as in #7830 I also had to add `__toString` method to entity.
Author
Owner

@lcobucci commented on GitHub (Oct 2, 2019):

@JKoty thanks! I'm not sure if using ParameterType::STRING + Connection::ARRAY_PARAM_OFFSET as type is actually supported and documented. How did you find this solution?

@lcobucci commented on GitHub (Oct 2, 2019): @JKoty thanks! I'm not sure if using `ParameterType::STRING + Connection::ARRAY_PARAM_OFFSET` as type is actually supported and documented. How did you find this solution?
Author
Owner

@JKoty commented on GitHub (Oct 2, 2019):

@lcobucci Actually it's from package kdyby/doctrine (here), line 74) so I'm not sure why is it even there. Maybe it should be fixed in their package. Dunno.

@JKoty commented on GitHub (Oct 2, 2019): @lcobucci Actually it's from package [kdyby/doctrine](https://github.com/Kdyby/Doctrine) ([here](https://github.com/Kdyby/Doctrine/blob/master/src/Kdyby/Doctrine/QueryBuilder.php)), line 74) so I'm not sure why is it even there. Maybe it should be fixed in their package. Dunno.
Author
Owner

@beberlei commented on GitHub (Dec 6, 2020):

Fixed in 2.7 as per related issue.

@beberlei commented on GitHub (Dec 6, 2020): Fixed in 2.7 as per related issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6311