EasyAdminBundle icon indicating copy to clipboard operation
EasyAdminBundle copied to clipboard

Ulid many to many - Autocomplete

Open pautier opened this issue 2 years ago • 5 comments

Describe the bug We worked on object (object1) with many to many relation with another object (object 2). The both objects use UUID id.

In the object 1 crud controller we set an associationField :

AssociationField::new('object2')->autocomplete()

So on the object 1 edit view , the autocomplete field display is ok and the autocomplete search works fine.

But when we want to save and update (persist) we received a format error :

An exception occurred while executing a query: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for type uuid: "01GH99K43SV8SB9NBPGS86574C"

The same error is display during the create process.

During our debug process :) we found the error source on the file : src/Form/EventListener/CrudAutocompleteSubscriber.php in EasyAdmin bundle on line 44/45.

The findBy on the id receive from the form an array with id in ULID format without transformation.

Note that it works fine with autocomplete many to one.

To Reproduce

easycorp/easyadmin-bundle : "v4.4.0"
symfony : "v6.1"

Use object with many to many relation with both UUID id.

(OPTIONAL) Additional context

We try to set a workaround and it seems to work :

$arrayAutoComplete = [];
if (is_array($data['autocomplete'])) {
    foreach ($data['autocomplete'] as $itemAutoComplete) {
        if (Ulid::isValid($itemAutoComplete)) {
            $arrayAutoComplete[] = Ulid::fromString($itemAutoComplete)->toRfc4122();
        } else {
            $arrayAutoComplete[] = $itemAutoComplete;
        }
    }
}
$options['choices'] = $options['em']->getRepository($options['class'])->findBy([
    $options['id_reader']->getIdField() => $arrayAutoComplete,
]);

Let me know if it's the good way to fix it.

pautier avatar Nov 08 '22 17:11 pautier

I have faced the same problem with UUID. We use UUID instead of ULID, but the problem exists and should be fixed ASAP. Thanks @pautier for your custom temporary hotfix. By the way instead of changing CrudAutocompleteSubscriber.php it is better to override findBy method in the entity repository you are using in many-to-many relationship, even though this way you need to override this method in other entity repositories probably used in many-to-many relationships.

public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
{
    if (isset($criteria['id']) && is_array($criteria['id'])) {
        $ids = [];
        foreach ($criteria['id'] as $id) {
            if (Uuid::isValid($id)) {
                $ids[] = Uuid::fromString($id)->toBinary();
            } else {
                $ids[] = $id;
            }
        }
        $criteria['id'] = $ids;
    }

    return parent::findBy($criteria, $orderBy, $limit, $offset);
}

So the ideal solution would be to see some fast hot-fix from @javiereguiluz. Please don't ignore this problem and take into account its urgency. Thanks in advance

bakhtiyor avatar Dec 07 '22 10:12 bakhtiyor

I have faced the same problem with UUID. We use UUID instead of ULID, but the problem exists and should be fixed ASAP. Thanks @pautier for your custom temporary hotfix. By the way instead of changing CrudAutocompleteSubscriber.php it is better to override findBy method in the entity repository you are using in many-to-many relationship, even though this way you need to override this method in other entity repositories probably used in many-to-many relationships.

public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
{
    if (isset($criteria['id']) && is_array($criteria['id'])) {
        $ids = [];
        foreach ($criteria['id'] as $id) {
            if (Uuid::isValid($id)) {
                $ids[] = Uuid::fromString($id)->toBinary();
            } else {
                $ids[] = $id;
            }
        }
        $criteria['id'] = $ids;
    }

    return parent::findBy($criteria, $orderBy, $limit, $offset);
}

So the ideal solution would be to see some fast hot-fix from @javiereguiluz. Please don't ignore this problem and take into account its urgency. Thanks in advance

->toRfc4122() worked for me instead of ->toBinary()

novelnet avatar May 15 '23 19:05 novelnet

Hello together, I am facing the exact same issue using ULID as an identifier in combination with MSSQL Server.

So that others looking for this issue will have it easier to find this one, here's my error message:

An exception occurred while executing a query: SQLSTATE[42000]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Conversion failed when converting from a character string to uniqueidentifier.

MaSpeng avatar May 24 '23 11:05 MaSpeng

Hey, I am facing the exact same issue would be nice to fix it and thanks

MedUnes avatar Jun 02 '23 15:06 MedUnes

Hello, same problem with ULID. I've the following error The choices "01H0MRCGT64S03SMSAB42Z79VB", "01H11WZBRBBFRYMZTEZMASCK02", "01H2FHXX8DR0V00QFERFJW0R6Q" do not exist in the choice list.

I tried to override findBy(), but when I dump $critera, there is no "id" key. Instead, there is another key of my entity. It's weird...

bastien70 avatar Mar 19 '24 13:03 bastien70