14

I have a Symfony2 form with a variety of fields, including one optional text field called recap.

This recap field saves perfectly when there's some text in it, but when the field is left blank, I get this error:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'recap' cannot be null

That's right - the column recap can't be null. I set it that way on purpose. Null means unknown. When the user leaves recap blank, the value of recap is not unknown; it's blank.

My question is how to get Symfony to save recap as '' when it's blank, not null.

2
  • Isn't this more of a problem on Doctrine's end? In that case, you could set the default value of the class' property to an empty string our use a custom DBAL\Types, which casts a null value to an emppty string. Commented Mar 29, 2012 at 15:41
  • I think you're right about it being on Doctrine's end. Setting the default value to an empty value didn't work for me, although I have seen claims in multiple places that that should work, which confuses me. Commented Mar 29, 2012 at 16:02

7 Answers 7

15

Go to your Entity and go to the declaration of the variables.

/**
 * @var string $name
 *
 * @ORM\Column(type="string", length=50)
 */
public $recap = '';

you can assign a default value for $recap.

Or otherway when you have the function setRecap you can check if empty or not set and set the value you expect.

public function setRecap($recap) {
   $this->recap = !isset($recap) ? '': $recap;
}

Or you set the default Value in your form Type to '' but i think then its not what you expect.

Sign up to request clarification or add additional context in comments.

5 Comments

Interesting. Neither of your suggestions worked by alone but when used together they did the trick. Thanks!
@ThomasDecaux: Then you should work with doctrine ;) thats wrong... Doctrine overwrite and build only functions that don't exist.
Cool, but still, its always a bad habit to mix your code with auto generated one, and this question is related to Form component so the solution must be in the same scope
@ThomasDecaux: no, you absolutely can modify the "generated" code (which doesn't necessarily even need to be generated). symfony.com/doc/current/book/… "This command makes sure that all of the getters and setters are generated for the Product class. This is a safe command - you can run it over and over again: it only generates getters and setters that don't exist (i.e. it doesn't replace your existing methods)." You shouldn't treat the Entities like some Doctrine magic, they are just regular PHP classes.
This is a pretty nasty hack. IF Sf2 or Doctrine fix the broken handling of empty strings, you could have unexpected results.
11

True, lost many hours on it ;-( the "transformation" is hardcoded in component Form.php line 1113 !

private function viewToNorm($value)
{
    $transformers = $this->config->getViewTransformers();

    if (!$transformers) {
        return '' === $value ? null : $value;
    }

    for ($i = count($transformers) - 1; $i >= 0; --$i) {
        $value = $transformers[$i]->reverseTransform($value);
    }

    return $value;
}

In my opinion, its a big error (because is the role of DataTransformer, not Form). So the solution is to create your own DataTransformer and associate it to the text type. Currently I am losing so much time with Symfony2, always seeking in the sources these kind of little hack ;-(

3 Comments

I was getting close to logging a bug about this because it seems utterly stupid. If you read their docs really closely it basically says if a text field is marked as required, an empty string will end up as an empty string but, if the field is optional, an empty string will be converted to null. See empty_data and required.
@thomas-decaux I have the same pain with Symfony2 - are you still working with it or have you found a better solution?
@jxmallett Did you ever log a bug? It'd make a great DX (Developer eXperience) ticket for Symfony
7

I have another solution for this issue:

create dummy class

class EmptyString {
    public function __toString() {
        return '';
    }
}

and set

$builder->add('recap', 'text', [
    'empty_data' => new EmptyString(),
]);

When entity will be stored to DB, it will automatically converted to empty string.

3 Comments

This was the solution for me too. I found that empty text boxes were treated as null values, and then forced directly into a sql statement, bypassing the Entity setter, so you can't catch null values there.
Why not doing just 'empty_data'=>'' ?
@the_nuts Because that's transformed to null, at least with symfony 2.4
5

I think you're taking the problem the wrong way: when the user leaves recap blank the value is unknown because not provided . For example you don't say that an empty birthdate field means that birthdate is equaled to '' but that birthdate is unknown. Same goes for addresss, etc...

So if your user isn't required to fill this field then it seems that the most relevant response is in fact to set your field as being nullable

1 Comment

I don't agree on this. A "complementary information" text field can either be empty (there is no complementary information) or null (unknown or irrelevant)
2

Just came across similar error in Symfony2:

My entity:

/**
 * @ORM\Column(type="boolean")
 */
protected $Valid;

My form:

$builder->add('Valid', 'hidden');

Now for true values, field is rendered correctly with value="1", but for false values field is rendered with value="", which leads to:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'Valid' cannot be null

While I would expect it to be rendered as value="0".

Of course setValid() method can be enhanced to set the right value:

public function setValid($valid)
{
    $this->Valid = ($valid ? true : false);
}

Which work arounds the issue, not fixes it.

Comments

2

In Forms, you can do:

$builder
->add('optionalField', TextType::class, ['required'=>false, 'empty_data'=>''])

Comments

-1

I also came across this problem. And an elegant solution was suggested to me was: to make this definition @ORM\Column(type="string", length=50, nullable=true)

3 Comments

Never use nullable value in a DB ! Its very bad for performance, prefer "" or 0.
@ThomasDecaux have you got any references for that? Is that for a particular RDBMS?
there's a good discussion on performance issues with NULL values (for SQL-alikes) here: link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.