Trying to access array offset on value of type null in BasicEntityPersister #7111

Open
opened 2026-01-22 15:44:52 +01:00 by admin · 18 comments
Owner

Originally created by @armellin on GitHub (Feb 17, 2023).

Bug Report

Q A
BC Break no
Version 2.14.1

Summary

In Persisters/Entity/BasicEntityPersister.php:1727 there is an access to $assoc['isOwningSide'] but $assoc may be null:

private function getSelectConditionStatementColumnSQL(
        string $field,
        ?array $assoc = null
    ): array
{
    // ........
                $joinColumns   = $assoc['isOwningSide']
                    ? $association['joinTable']['joinColumns']
                    : $association['joinTable']['inverseJoinColumns'];

Current behavior

Validating an Entity with a ManyToMany association, I got that error.

Originally created by @armellin on GitHub (Feb 17, 2023). ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | Q | A |------------ | ------ | BC Break | no | Version | 2.14.1 #### Summary In Persisters/Entity/BasicEntityPersister.php:1727 there is an access to $assoc['isOwningSide'] but $assoc may be null: ```php private function getSelectConditionStatementColumnSQL( string $field, ?array $assoc = null ): array { // ........ $joinColumns = $assoc['isOwningSide'] ? $association['joinTable']['joinColumns'] : $association['joinTable']['inverseJoinColumns']; ``` #### Current behavior Validating an Entity with a ManyToMany association, I got that error.
Author
Owner

@mpdude commented on GitHub (Feb 19, 2023):

Thank you for the bug report!

To help us reproduce this, could you try to provide the two entities in questions (those with the relationship between each other) and reduce them to the minimum amount of code that still causes the error?

My guess would be that you can remove all methods and fields except the IDs and the association.

There were no recent relevant changes in that area of the code. I am suspecting some kind of misconfiguration. Anyways, we should spot that and give a helpful error message, not fail with an error like this.

@mpdude commented on GitHub (Feb 19, 2023): Thank you for the bug report! To help us reproduce this, could you try to provide the two entities in questions (those with the relationship between each other) and reduce them to the minimum amount of code that still causes the error? My guess would be that you can remove all methods and fields except the IDs and the association. There were no recent relevant changes in that area of the code. I am suspecting some kind of misconfiguration. Anyways, we should spot that and give a helpful error message, not fail with an error like this.
Author
Owner

@armellin commented on GitHub (Feb 19, 2023):

I have the same suspicion, especially because all other associations work perfectly. Digging more I have found that it's caused by:

#[UniqueEntity(fields: [................, "products"], message: "......", ignoreNull: false]

in the entity which is the owning side of the ManyToMany association with the Product entity.

If I cut the "products" away from the fields list, everything works.

Before testing more, is it supported to have a ManyToMany association in the UniqueEntity constraint?

@armellin commented on GitHub (Feb 19, 2023): I have the same suspicion, especially because all other associations work perfectly. Digging more I have found that it's caused by: ```php #[UniqueEntity(fields: [................, "products"], message: "......", ignoreNull: false] ``` in the entity which is the owning side of the ManyToMany association with the Product entity. If I cut the "products" away from the fields list, everything works. Before testing more, is it supported to have a ManyToMany association in the UniqueEntity constraint?
Author
Owner

@mpdude commented on GitHub (Feb 20, 2023):

You have not provided any entity code, configuration or stack traces yet, which makes it difficult for others to understand the situation.

If you think it’s related to a UniqueEntity constraint (which might be confirmed by a stack trace), that seems to be a Symfony thing and you’d need to ask over at their repo.

@mpdude commented on GitHub (Feb 20, 2023): You have not provided any entity code, configuration or stack traces yet, which makes it difficult for others to understand the situation. If you think it’s related to a `UniqueEntity` constraint (which might be confirmed by a stack trace), that seems to be a Symfony thing and you’d need to ask over at their repo.
Author
Owner

@armellin commented on GitHub (Feb 20, 2023):

Ok, thanks.

But, anyway, shouldn't we test if $assoc is not null (which might be, according to the method's signature) before accessing $assoc['isOwningSide'] ?
Or is it overengineering?
Feel free to close this issue if you think that it's not necessary.

@armellin commented on GitHub (Feb 20, 2023): Ok, thanks. But, anyway, shouldn't we test if $assoc is not null (which might be, according to the method's signature) before accessing $assoc['isOwningSide'] ? Or is it overengineering? Feel free to close this issue if you think that it's not necessary.
Author
Owner

@mpdude commented on GitHub (Feb 20, 2023):

I agree we should, but probably it can not be more than a generic InvalidArgumentException in that place.

The parameter is passed through a lot of methods apparently (and the same pattern/problem might occur elsewhere?). To give a more meaningful exception message, we probably have to find a suitable place higher up?

@mpdude commented on GitHub (Feb 20, 2023): I agree we should, but probably it can not be more than a generic `InvalidArgumentException` in that place. The parameter is passed through a lot of methods apparently (and the same pattern/problem might occur elsewhere?). To give a more meaningful exception message, we probably have to find a suitable place higher up?
Author
Owner

@AnthonyANI commented on GitHub (Apr 26, 2023):

I'm running into this same bug with BasicEntityPersister. It is indeed reproduced by UniqueEntityValidator for validating a constraint on a Collection/ManyToMany which calls default repository method findBy() to do so.

Line 1724 in BasicEntityPersister is using $assoc when it seems it should be using $association as $assoc is null (which is valid per the method signature as mentioned by @armellin) and $association isn't and has the 'isOwningSide' key and value ready for use. @mpdude Is that intentional? Thanks!
image
image

This is what's passed to findBy() of EntityRepository and loadAll() of BasicEntityPersister:
image

From there, loadAll() of BasicEntityPersister passes a null to $assoc (default null), which plays out to the error.
image
image

Full callstack if you need it:

Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getSelectConditionStatementColumnSQL (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:1724)
Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getSelectConditionStatementSQL (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:1628)
Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getSelectConditionSQL (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:1778)
Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getSelectSQL (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:1092)
Doctrine\ORM\Persisters\Entity\BasicEntityPersister->loadAll (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:914)
Doctrine\ORM\EntityRepository->findBy (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php:225)
Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator->validate (\var\www\vendor\symfony\doctrine-bridge\Validator\Constraints\UniqueEntityValidator.php:153)
Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateInGroup (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:759)
Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateClassNode (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:488)
Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateObject (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:313)
Symfony\Component\Validator\Validator\RecursiveContextualValidator->validate (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:138)
Symfony\Component\Form\Extension\Validator\Constraints\FormValidator->validate (\var\www\vendor\symfony\form\Extension\Validator\Constraints\FormValidator.php:108)
Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateInGroup (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:759)
Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateClassNode (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:488)
Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateObject (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:313)
Symfony\Component\Validator\Validator\RecursiveContextualValidator->validate (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:138)
Symfony\Component\Validator\Validator\RecursiveValidator->validate (\var\www\vendor\symfony\validator\Validator\RecursiveValidator.php:93)
Symfony\Component\Validator\Validator\TraceableValidator->validate (\var\www\vendor\symfony\validator\Validator\TraceableValidator.php:66)
Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener->validateForm (\var\www\vendor\symfony\form\Extension\Validator\EventListener\ValidationListener.php:50)
Symfony\Component\EventDispatcher\EventDispatcher->callListeners (\var\www\vendor\symfony\event-dispatcher\EventDispatcher.php:230)
@AnthonyANI commented on GitHub (Apr 26, 2023): I'm running into this same bug with BasicEntityPersister. It is indeed reproduced by UniqueEntityValidator for validating a constraint on a Collection/ManyToMany which calls default repository method findBy() to do so. Line 1724 in BasicEntityPersister is using $assoc when it seems it should be using $association as $assoc is null (which is valid per the method signature as mentioned by @armellin) and $association isn't and has the 'isOwningSide' key and value ready for use. @mpdude Is that intentional? Thanks! ![image](https://user-images.githubusercontent.com/1095768/234653201-9c0cc89b-fa9d-4f8f-845f-50149b4181e5.png) ![image](https://user-images.githubusercontent.com/1095768/234653411-a454a12f-8184-44eb-a1be-66256d1259a8.png) This is what's passed to findBy() of EntityRepository and loadAll() of BasicEntityPersister: ![image](https://user-images.githubusercontent.com/1095768/234655070-3168cfcd-5d15-48b7-9a38-1a008c4b570f.png) From there, loadAll() of BasicEntityPersister passes a null to $assoc (default null), which plays out to the error. ![image](https://user-images.githubusercontent.com/1095768/234661972-3e8812e2-30e9-42e7-a775-05238fe0f1db.png) ![image](https://user-images.githubusercontent.com/1095768/234662078-ff5c3393-08db-46bd-89b2-febfcbfbe3be.png) Full callstack if you need it: ``` Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getSelectConditionStatementColumnSQL (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:1724) Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getSelectConditionStatementSQL (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:1628) Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getSelectConditionSQL (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:1778) Doctrine\ORM\Persisters\Entity\BasicEntityPersister->getSelectSQL (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:1092) Doctrine\ORM\Persisters\Entity\BasicEntityPersister->loadAll (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php:914) Doctrine\ORM\EntityRepository->findBy (\var\www\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php:225) Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator->validate (\var\www\vendor\symfony\doctrine-bridge\Validator\Constraints\UniqueEntityValidator.php:153) Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateInGroup (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:759) Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateClassNode (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:488) Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateObject (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:313) Symfony\Component\Validator\Validator\RecursiveContextualValidator->validate (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:138) Symfony\Component\Form\Extension\Validator\Constraints\FormValidator->validate (\var\www\vendor\symfony\form\Extension\Validator\Constraints\FormValidator.php:108) Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateInGroup (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:759) Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateClassNode (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:488) Symfony\Component\Validator\Validator\RecursiveContextualValidator->validateObject (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:313) Symfony\Component\Validator\Validator\RecursiveContextualValidator->validate (\var\www\vendor\symfony\validator\Validator\RecursiveContextualValidator.php:138) Symfony\Component\Validator\Validator\RecursiveValidator->validate (\var\www\vendor\symfony\validator\Validator\RecursiveValidator.php:93) Symfony\Component\Validator\Validator\TraceableValidator->validate (\var\www\vendor\symfony\validator\Validator\TraceableValidator.php:66) Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener->validateForm (\var\www\vendor\symfony\form\Extension\Validator\EventListener\ValidationListener.php:50) Symfony\Component\EventDispatcher\EventDispatcher->callListeners (\var\www\vendor\symfony\event-dispatcher\EventDispatcher.php:230) ```
Author
Owner

@wizzyto12 commented on GitHub (Aug 23, 2023):

I have the same issue.

@wizzyto12 commented on GitHub (Aug 23, 2023): I have the same issue.
Author
Owner

@apastorsales commented on GitHub (Aug 25, 2023):

I have the same issue.

@apastorsales commented on GitHub (Aug 25, 2023): I have the same issue.
Author
Owner

@FlyingDR commented on GitHub (Dec 1, 2023):

@mpdude I've faced the same issue trying to use \Doctrine\ORM\EntityRepository::findBy() with the $criteria that references many-to-many association.

Relevant parts of entities:

Table.php

#[ORM\Entity]
#[ORM\Table('tables')]
class Table 
{
    #[ORM\Id]
    #[ORM\Column]
    private int $id; 

    #[ORM\ManyToMany(targetEntity: Mode::class, inversedBy: 'tables', cascade: ['persist', 'remove'])]
    #[JoinTable(name: 'table_modes')]
    private Collection $modes;

    // ...
}

Mode.php

#[ORM\Entity]
#[ORM\Table('modes')]
class Mode 
{
    #[ORM\Id]
    #[ORM\Column(length: 10, unique: true)]
    private string $id;

    #[ORM\ManyToMany(targetEntity: Table::class, mappedBy: 'modes')]
    private Collection $tables;

    // ...
}

Code that produces the issue:

$tables = $this->em->getRepository(Table::class)->findBy(['modes'=>'test']);

findBy() calls loadAll() with null for $assoc argument and this null is passed down to the location, mentioned in the issue description.

Stack for the issue is:

\Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectConditionStatementColumnSQL()
\Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectConditionStatementSQL()
\Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectConditionSQL()
\Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectSQL()
\Doctrine\ORM\Persisters\Entity\BasicEntityPersister::loadAll()
\Doctrine\ORM\EntityRepository::findBy()

From the Git history, it can be seen, that the code that caused the issue was added by https://github.com/doctrine/orm/pull/1249, but it was a long time ago.

There is possibly another issue at the same place:

23d36c0d52/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php (L1745-L1752)

If the condition on the line 1745 is true then there will be TypeError in line 1749 because of a type mismatch: 23d36c0d52/lib/Doctrine/ORM/Mapping/QuoteStrategy.php (L49)

From the local context at the place of the issue, it looks like the real issue is the idea of passing the $assoc argument to this method at all. getSelectConditionStatementColumnSQL() method is only called from the getSelectConditionStatementSQL() and it is only used for many-to-many associations. Also, by the time of using the $assoc argument the association for it is already resolved in the $association field.

What is interesting is that in 3.x branch affected code includes assertion, so it will result in AssertionError instead of warning: f8ced51687/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php (L1655)

@FlyingDR commented on GitHub (Dec 1, 2023): @mpdude I've faced the same issue trying to use `\Doctrine\ORM\EntityRepository::findBy()` with the `$criteria` that references many-to-many association. Relevant parts of entities: Table.php ```php #[ORM\Entity] #[ORM\Table('tables')] class Table { #[ORM\Id] #[ORM\Column] private int $id; #[ORM\ManyToMany(targetEntity: Mode::class, inversedBy: 'tables', cascade: ['persist', 'remove'])] #[JoinTable(name: 'table_modes')] private Collection $modes; // ... } ``` Mode.php ```php #[ORM\Entity] #[ORM\Table('modes')] class Mode { #[ORM\Id] #[ORM\Column(length: 10, unique: true)] private string $id; #[ORM\ManyToMany(targetEntity: Table::class, mappedBy: 'modes')] private Collection $tables; // ... } ``` Code that produces the issue: ```php $tables = $this->em->getRepository(Table::class)->findBy(['modes'=>'test']); ``` `findBy()` calls `loadAll()` with `null` for `$assoc` argument and this `null` is passed down to the [location](https://github.com/doctrine/orm/blob/23d36c0d5293ac796f35850b4f082aef60c6fc52/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php#L1750), mentioned in the issue description. Stack for the issue is: ``` \Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectConditionStatementColumnSQL() \Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectConditionStatementSQL() \Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectConditionSQL() \Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectSQL() \Doctrine\ORM\Persisters\Entity\BasicEntityPersister::loadAll() \Doctrine\ORM\EntityRepository::findBy() ``` From the Git history, it can be seen, that the code that caused the issue was added by https://github.com/doctrine/orm/pull/1249, but it was a long time ago. There is possibly another issue at the same place: https://github.com/doctrine/orm/blob/23d36c0d5293ac796f35850b4f082aef60c6fc52/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php#L1745-L1752 If the condition on the line 1745 is true then there will be `TypeError` in line 1749 because of a type mismatch: https://github.com/doctrine/orm/blob/23d36c0d5293ac796f35850b4f082aef60c6fc52/lib/Doctrine/ORM/Mapping/QuoteStrategy.php#L49 From the local context at the place of the issue, it looks like the real issue is the idea of passing the `$assoc` argument to this method at all. `getSelectConditionStatementColumnSQL()` method is only called from the `getSelectConditionStatementSQL()` and it is only used for many-to-many associations. Also, by the time of using the `$assoc` argument the association for it is already resolved in the `$association` field. What is interesting is that in 3.x branch affected code includes assertion, so it will result in `AssertionError` instead of warning: https://github.com/doctrine/orm/blob/f8ced516879a7583cb0b167bb5df0e1b04f32fa5/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php#L1655
Author
Owner

@samharvey44 commented on GitHub (Dec 8, 2023):

As above, also experiencing this error - it seems to occur when attempting a findBy or findOneBy on a ManyToMany relationship with no inverse relation.

@samharvey44 commented on GitHub (Dec 8, 2023): As above, also experiencing this error - it seems to occur when attempting a `findBy` or `findOneBy` on a `ManyToMany` relationship with no inverse relation.
Author
Owner

@jklmnop commented on GitHub (Feb 7, 2024):

Also experiencing this.

@jklmnop commented on GitHub (Feb 7, 2024): Also experiencing this.
Author
Owner

@mateusfmello commented on GitHub (Feb 26, 2024):

I'm also having the same problem with

Doctrine version: 2.9

#[ORM\ManyToMany(targetEntity: Produto::class)]
@mateusfmello commented on GitHub (Feb 26, 2024): I'm also having the same problem with Doctrine version: `2.9` ``` #[ORM\ManyToMany(targetEntity: Produto::class)] ```
Author
Owner

@karrakoliko commented on GitHub (Apr 24, 2024):

Experiencing the same when trying to use Criteria with contains expression.

Product.php:

class Product {

    #[ORM\ManyToMany(targetEntity: Category::class, inversedBy: 'products', cascade: ['persist'])]
    #[ORM\JoinTable(name: 'product_category')]
    private Collection $categories;
    
}

Category.php:

class Category {
    #[ORM\ManyToMany(targetEntity: Product::class, mappedBy: 'categories')]
    #[ORM\JoinTable(name: 'product_category')]
    private Collection $products;

}

Criteria:

        $criteria = new Criteria();

        $category = ***; // Category instance
        $criteria->andWhere(Criteria::expr()->contains('categories', $category));

Call:

$productRepository->matching($criteria)

Error:

Trying to access array offset on value of type null
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1750
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1654
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php:59
 /var/www/sharmax-motors/vendor/doctrine/collections/src/Expr/ExpressionVisitor.php:46
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1645
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1161
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:870
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/LazyCriteriaCollection.php:61
...
@karrakoliko commented on GitHub (Apr 24, 2024): Experiencing the same when trying to use Criteria with `contains` expression. Product.php: ```php class Product { #[ORM\ManyToMany(targetEntity: Category::class, inversedBy: 'products', cascade: ['persist'])] #[ORM\JoinTable(name: 'product_category')] private Collection $categories; } ``` Category.php: ```php class Category { #[ORM\ManyToMany(targetEntity: Product::class, mappedBy: 'categories')] #[ORM\JoinTable(name: 'product_category')] private Collection $products; } ``` Criteria: ```php $criteria = new Criteria(); $category = ***; // Category instance $criteria->andWhere(Criteria::expr()->contains('categories', $category)); ``` Call: ```php $productRepository->matching($criteria) ``` Error: ``` Trying to access array offset on value of type null /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1750 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1654 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php:59 /var/www/sharmax-motors/vendor/doctrine/collections/src/Expr/ExpressionVisitor.php:46 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1645 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1161 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:870 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/LazyCriteriaCollection.php:61 ... ```
Author
Owner

@mateusfmello commented on GitHub (Apr 29, 2024):

Experiencing the same when trying to use Criteria with contains expression.

Product.php:

class Product {

    #[ORM\ManyToMany(targetEntity: Category::class, inversedBy: 'products', cascade: ['persist'])]
    #[ORM\JoinTable(name: 'product_category')]
    private Collection $categories;
    
}

Category.php:

class Category {
    #[ORM\ManyToMany(targetEntity: Product::class, mappedBy: 'categories')]
    #[ORM\JoinTable(name: 'product_category')]
    private Collection $products;

}

Criteria:

        $criteria = new Criteria();

        $category = ***; // Category instance
        $criteria->andWhere(Criteria::expr()->contains('categories', $category));

Call:

$productRepository->matching($criteria)

Error:

Trying to access array offset on value of type null
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1750
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1654
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php:59
 /var/www/sharmax-motors/vendor/doctrine/collections/src/Expr/ExpressionVisitor.php:46
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1645
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1161
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:870
 /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/LazyCriteriaCollection.php:61
...

My code is exactly like this, same relationship and this error also occurs.

Doctrine version: 2.19.3

@mateusfmello commented on GitHub (Apr 29, 2024): > Experiencing the same when trying to use Criteria with `contains` expression. > > Product.php: > > ``` > class Product { > > #[ORM\ManyToMany(targetEntity: Category::class, inversedBy: 'products', cascade: ['persist'])] > #[ORM\JoinTable(name: 'product_category')] > private Collection $categories; > > } > ``` > > Category.php: > > ``` > class Category { > #[ORM\ManyToMany(targetEntity: Product::class, mappedBy: 'categories')] > #[ORM\JoinTable(name: 'product_category')] > private Collection $products; > > } > ``` > > Criteria: > > ``` > $criteria = new Criteria(); > > $category = ***; // Category instance > $criteria->andWhere(Criteria::expr()->contains('categories', $category)); > ``` > > Call: > > ``` > $productRepository->matching($criteria) > ``` > > Error: > > ``` > Trying to access array offset on value of type null > /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1750 > /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1654 > /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php:59 > /var/www/sharmax-motors/vendor/doctrine/collections/src/Expr/ExpressionVisitor.php:46 > /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1645 > /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:1161 > /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:870 > /var/www/sharmax-motors/vendor/doctrine/orm/lib/Doctrine/ORM/LazyCriteriaCollection.php:61 > ... > ``` My code is exactly like this, same relationship and this error also occurs. Doctrine version: `2.19.3`
Author
Owner

@karrakoliko commented on GitHub (Apr 29, 2024):

My code is exactly like this, same relationship and this error also occurs.

Doctrine version: 2.9

Actually, solution is to use product repository's query builder.

some ProductRepository method:

// @var array<Category> $categories array of Category instances
$categories = [];

$categoryAlias = 'c';
$qb = $this->createQueryBuilder('p');
$qb->innerJoin('p.categories', $categoryAlias);

$criteria = Criteria::create();

$criteria->andWhere(Criteria::expr()->in(sprintf('%s.id', $categoryAlias),$categories));

$qb->addCriteria($criteria);

$query->execute(); // array of products that are in one of given categories

There must be a more clear error message though.
Is error happens because of relation join clause not added?

@karrakoliko commented on GitHub (Apr 29, 2024): > My code is exactly like this, same relationship and this error also occurs. > > Doctrine version: `2.9` Actually, solution is to use product repository's query builder. some `ProductRepository` method: ```php // @var array<Category> $categories array of Category instances $categories = []; $categoryAlias = 'c'; $qb = $this->createQueryBuilder('p'); $qb->innerJoin('p.categories', $categoryAlias); $criteria = Criteria::create(); $criteria->andWhere(Criteria::expr()->in(sprintf('%s.id', $categoryAlias),$categories)); $qb->addCriteria($criteria); $query->execute(); // array of products that are in one of given categories ``` There must be a more clear error message though. Is error happens because of relation join clause not added?
Author
Owner

@mateusfmello commented on GitHub (Apr 29, 2024):

My code is exactly like this, same relationship and this error also occurs.
Doctrine version: 2.9

Actually, solution is to use product repository's query builder.

some ProductRepository method:

// @var array<Category> $categories array of Category instances
$categories = [];

$categoryAlias = 'c';
$qb = $this->createQueryBuilder('p');
$qb->innerJoin('p.categories', $categoryAlias);

$criteria = Criteria::create();

$criteria->andWhere(Criteria::expr()->in(sprintf('%s.id', $categoryAlias),$categories));

$qb->addCriteria($criteria);

$query->execute(); // array of products that are in one of given categories

There must be a more clear error message though. Is error happens because of relation join clause not added?

I don't know why this happens, I haven't investigated the problem yet, I'll try your approach today if possible, after testing I'll get back to you for feedback.

@mateusfmello commented on GitHub (Apr 29, 2024): > > My code is exactly like this, same relationship and this error also occurs. > > Doctrine version: `2.9` > > Actually, solution is to use product repository's query builder. > > some `ProductRepository` method: > > ``` > // @var array<Category> $categories array of Category instances > $categories = []; > > $categoryAlias = 'c'; > $qb = $this->createQueryBuilder('p'); > $qb->innerJoin('p.categories', $categoryAlias); > > $criteria = Criteria::create(); > > $criteria->andWhere(Criteria::expr()->in(sprintf('%s.id', $categoryAlias),$categories)); > > $qb->addCriteria($criteria); > > $query->execute(); // array of products that are in one of given categories > ``` > > There must be a more clear error message though. Is error happens because of relation join clause not added? I don't know why this happens, I haven't investigated the problem yet, I'll try your approach today if possible, after testing I'll get back to you for feedback.
Author
Owner

@mateusfmello commented on GitHub (Apr 29, 2024):

My code is exactly like this, same relationship and this error also occurs.
Doctrine version: 2.9

Actually, solution is to use product repository's query builder.

some ProductRepository method:

// @var array<Category> $categories array of Category instances
$categories = [];

$categoryAlias = 'c';
$qb = $this->createQueryBuilder('p');
$qb->innerJoin('p.categories', $categoryAlias);

$criteria = Criteria::create();

$criteria->andWhere(Criteria::expr()->in(sprintf('%s.id', $categoryAlias),$categories));

$qb->addCriteria($criteria);

$query->execute(); // array of products that are in one of given categories

There must be a more clear error message though. Is error happens because of relation join clause not added?

$query is $qb?

Because $qb does not have the execute method

@mateusfmello commented on GitHub (Apr 29, 2024): > > My code is exactly like this, same relationship and this error also occurs. > > Doctrine version: `2.9` > > Actually, solution is to use product repository's query builder. > > some `ProductRepository` method: > > ``` > // @var array<Category> $categories array of Category instances > $categories = []; > > $categoryAlias = 'c'; > $qb = $this->createQueryBuilder('p'); > $qb->innerJoin('p.categories', $categoryAlias); > > $criteria = Criteria::create(); > > $criteria->andWhere(Criteria::expr()->in(sprintf('%s.id', $categoryAlias),$categories)); > > $qb->addCriteria($criteria); > > $query->execute(); // array of products that are in one of given categories > ``` > > There must be a more clear error message though. Is error happens because of relation join clause not added? `$query` is `$qb`? Because `$qb` does not have the `execute` method
Author
Owner

@mateusfmello commented on GitHub (Apr 29, 2024):

@karrakoliko This solution is not ideal for me, because in my case I have clients and groups, where a client can have many groups and groups can have many clients, and I use the limit 5 for clients, so the result is less than 5 clients, because Some of the clients have more than one group, so the query result repeats clients, but with different groups.

Table clients

id name
1 name 1
2 name 2
3 name 3
4 name 4
5 name 5
6 name 6
7 name 7

Table groups

id name
1 group 1
2 group 2
3 group 3

Table clients_groups

client_id group_id
1 1
1 2
1 3
2 1
3 1
4 3

Query result returns only 3 clients, but what was expected was 5, where the client with id 1 returned with 3 groups

@mateusfmello commented on GitHub (Apr 29, 2024): @karrakoliko This solution is not ideal for me, because in my case I have clients and groups, where a client can have many groups and groups can have many clients, and I use the limit 5 for clients, so the result is less than 5 clients, because Some of the clients have more than one group, so the query result repeats clients, but with different groups. Table `clients` |id|name | |--|--| | 1 | name 1 | | 2 | name 2 | | 3 | name 3 | | 4 | name 4 | | 5 | name 5 | | 6 | name 6 | | 7 | name 7 | Table `groups` |id|name |--|--| | 1 | group 1 | | 2 | group 2 | | 3 | group 3 | Table `clients_groups` |client_id|group_id |--|--| | 1 | 1 | | 1 | 2 | | 1 | 3 | | 2 | 1 | | 3 | 1 | | 4 | 3 | Query result returns only 3 clients, but what was expected was 5, where the client with id 1 returned with 3 groups
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7111