"This value is not valid" when using "query_builder" on "entity" buildForm on symfony2.1
Asked Answered
S

3

3

Here is my problem. I use the buildForm method on symfony 2.1 in order to build my form. With the following code everything works just fine :

$builder->add('combat','entity',array(
                    class' => 'KarateCompetitionBundle:CompetitionCombat',
                    'empty_value' => 'Sélectionner un combat'));

But I want to filter and display only some Combat. That's why I have to use the query_builder option. When i do that i get the This value is not valid error message. Here is the code :

$builder->add('combat','entity',array(
                  'class' => 'KarateCompetitionBundle:CompetitionCombat',
                  'empty_value' => 'Sélectionner un combat',
                  'query_builder' => function(CombatRepository $cr) {
                      return $cr->getAllWithoutBilanQueryBuilder();}));

I reduce at the minimum the code (i.e. no filtering on the getAllWithoutBilanQueryBuildermethod) in order to be able to find the problem.

public function getAllWithoutBilanQueryBuilder(){
    $queryBuilder = $this->getEntityManager()->createQueryBuilder();
    return $queryBuilder->select('c')->from('KarateEntrainementBundle:CompetitionCombat', 'c');

}

I've compared both html code generate on each case and they are the same.

I put a var_dump($object) on the controller after binding the form with the request $form->bind($request) and it appears that when i use the query_builder option the combatis null while it is not null if i don't use it.

I can't manage to understand why ? I found few post on the web with the same issue but none with an answer. Is it possible that there is a symfony issue here or am I doing something wrong ?

Separates answered 4/3, 2013 at 0:32 Comment(9)
It's probably just a copy/paste thing but you do have two different method names: getAllWithoutScoreQueryBuilder and getAllWithoutBilanQueryBuilder. $this->ENTITY seems a bit suspicious. Does it work if you just return the created queryBuilder form your method? Make a command object or unittest and verify that a valid query builder is being returned with CompetitionCombat objects as the result.Toandfro
Thanks. Yes, it was a copy/past thing. I edit my question to correct that. $this->Entity is a global variable in order not to repeat each time. I edit my question and replace it for better understanding. Actually, I know the querybuilder is correct because my form is well generated. I have the list of combats. But when i select one, and validate the form then I have the error message. What is weird is that if i put the query_builder property or if I don't, both html codes are the same. But without the query_builder property I can select a combat and validate and there is no error.Separates
You only have one entity manager and it is named default?Toandfro
I don't understand the question. I guess, yes, I only have one entity manager. I get it via $this->getEntityManager from a custom repository that extends EntityRepositorySeparates
It's possible to have multiple entity managers, each with a different name in which case you need to set the em parameter. But clearly you are not doing that.Toandfro
Are you doing any special validation? Do you have a validation.yml file? Just kind of shooting in the dark here.Toandfro
I do not have a validation file. But I have some validation on Combat entity : UniqueConstraint(columns={"idCompetition", "idCategorie","tour"})})on the table ; @UniqueEntity(fields={"competition","categorie","tour"},message="my error message") and @Assert\Callback(methods={"isValid"}) on the class. With public function isValid(ExecutionContext $context){if ($this->finale && $this->demiFinale){$context->addViolation('message erreur', array(), null);}}Separates
But i do not think these validations are relevant on that problem.Separates
And thank you. I didn't know abut the possibility of having many entity managers.Separates
S
0

I finally managed to make this worked :-)

So here was the fix. On the getAllWithoutBilanQueryBuilder function, I replace

$queryBuilder = $this->getEntityManager()->createQueryBuilder(); 

by

$queryBuilder = $this->createQueryBuilder('c');

I don't know what is exactly the difference and why this is now working. But this is working.

Thanks you all for your help.

Separates answered 30/4, 2013 at 18:36 Comment(0)
C
1

I had the exact same problem and - in my case - traced it back to Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader.

When the form is validated, the entities are loaded by primary key in ORMQueryBuilderLoader::getEntitiesByIds() by adding an IN() clause to the query builder. In my case, this IN() clause was ineffective and all selectable entities were returned.

This, in turn, caused Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToValuesTransformer::reverseTransform() to throw a TransformationFailedException, because the number of loaded entities and submitted choices were not the same.

I suppose there's other possible causes for this specific error. Here's what you could try:

  • Look at the generated query, run it manually and make sure it returns only the selected values
  • In Symfony\Component\Form\Form, try outputting the caught TransformationFailedException and see where it leads you.
  • If none of the above seem plausible, add some debug output to Symfony\Component\Form\Extension\Validator\Constraints\FormValidator and see whether you can narrow it down somewhat.
Caryopsis answered 19/4, 2013 at 21:47 Comment(2)
Thanks for your help ! So I've try what you said. I've executed the query manually and everything is ok. Then i output the TransofrmationFailedException. Here is the error message : The choice "16" does not exist or is not unique. "16" is the id of the selected combat. And as a matter of fact, I check the DB and there is a combat with the id "16" and there is only one. So I didn't understand why I get this error. Thank you for your help. At least now, i know a little more. :-)Separates
@Mike I 'm running into the exact same issue too, with the same symptoms, ie: at validation, a 'IN' is added to the DB query making the validation failing as the submitted value isn't anymore in the possible values :(... How can we get rid of this 'IN' that get added automatically ?Imbed
S
1

As an addition to @mike-b answer: for me failing QueryBuilder statement was ->having('...') query part:

    ...
    'query_builder' => function(EntityRepository $er) use ($pn) {
                    return $er->createQueryBuilder('p')
                                    ->select('p')
                                    ->join('p.product', 'pr')
                                    ->where('p.name = ' . $pn->getId())
                                    ->andWhere("LENGTH(p.value_en) > 1")
                                    ->andWhere("p.value_en != ''")
                                    /* when I remove this - validation passe flawlessly  */
                                    ->having('COUNT(pr.id) > 1')
                                    ->groupBy('p.value_en)
                                    ->orderBy('p.value_en', 'ASC');
    ...

tested with Symfony version 2.3.6

Subcutaneous answered 6/11, 2013 at 10:55 Comment(0)
S
0

I finally managed to make this worked :-)

So here was the fix. On the getAllWithoutBilanQueryBuilder function, I replace

$queryBuilder = $this->getEntityManager()->createQueryBuilder(); 

by

$queryBuilder = $this->createQueryBuilder('c');

I don't know what is exactly the difference and why this is now working. But this is working.

Thanks you all for your help.

Separates answered 30/4, 2013 at 18:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.