DDC-3794: Cannot set default value on a @joinColumn #4649

Closed
opened 2026-01-22 14:46:45 +01:00 by admin · 13 comments
Owner

Originally created by @doctrinebot on GitHub (Jun 25, 2015).

Originally assigned to: @Ocramius on GitHub.

Jira issue originally created by user bmeynell:

The @Column allows for {{options={"default":1})}}.

However, @joinColumn does not support {{options={"default":1})}}.

The implication of this is that a default value can never be set for new database schemas and for existing schemas that have DEFAULT '1' included in its column definition a schema mismatch will occur when running doctrine:schema:validate.

Since there is no way to define a default on the entity-level there is no way to reconcile the mismatch. Instead, the default value just be removed from the database schema and be enforced on the application level.

Originally created by @doctrinebot on GitHub (Jun 25, 2015). Originally assigned to: @Ocramius on GitHub. Jira issue originally created by user bmeynell: The `@Column` allows for {{options={"default":1})}}. However, `@joinColumn` does not support {{options={"default":1})}}. The implication of this is that a default value can **never** be set for _new_ database schemas and for _existing_ schemas that have `DEFAULT '1'` included in its column definition a schema mismatch will occur when running `doctrine:schema:validate`. Since there is no way to define a default on the entity-level there is no way to reconcile the mismatch. Instead, the default value just be removed from the database schema and be enforced on the application level.
admin added the New FeatureWon't FixInvalid labels 2026-01-22 14:46:45 +01:00
admin closed this issue 2026-01-22 14:46:45 +01:00
Author
Owner

@doctrinebot commented on GitHub (Oct 12, 2015):

Comment created by fbnatvista:

I'm not sure if there is any controindication bu adding Column annotation with the JoinColumn may bypass the problem:

/****
     * @var \ApiMart\Models\Country
     *
     * @ORM\ManyToOne(targetEntity="ApiMart\Models\Country", inversedBy="addressList")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="country*id", referencedColumnName="country*id", nullable=false)
     * })
     * @ORM\Column(name="country_id", type="integer", options={"default":0})
     */
    protected $country;
@doctrinebot commented on GitHub (Oct 12, 2015): Comment created by fbnatvista: I'm not sure if there is any controindication bu adding Column annotation with the JoinColumn may bypass the problem: ``` java /**** * @var \ApiMart\Models\Country * * @ORM\ManyToOne(targetEntity="ApiMart\Models\Country", inversedBy="addressList") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="country*id", referencedColumnName="country*id", nullable=false) * }) * @ORM\Column(name="country_id", type="integer", options={"default":0}) */ protected $country; ```
Author
Owner

@doctrinebot commented on GitHub (Oct 25, 2015):

Comment created by pat1498:

Sorry, I accidentally pressed the 'request feedback' button. I just wanted to say, the proposed solution does not seem to work. When I add the extra ORM\Column annotation, and run a migrations:diff... the migration shows that the foreign key and index will be dropped.

I have also tried using the columnDefinition annotation inside JoinColumn, but it doesn't seem to get picked up by a diff.

@doctrinebot commented on GitHub (Oct 25, 2015): Comment created by pat1498: Sorry, I accidentally pressed the 'request feedback' button. I just wanted to say, the proposed solution does not seem to work. When I add the extra ORM\Column annotation, and run a migrations:diff... the migration shows that the foreign key and index will be dropped. I have also tried using the columnDefinition annotation inside JoinColumn, but it doesn't seem to get picked up by a diff.
Author
Owner

@maior-valentin commented on GitHub (May 5, 2016):

Hey guys. Any news on this?

@maior-valentin commented on GitHub (May 5, 2016): Hey guys. Any news on this?
Author
Owner

@hmillet commented on GitHub (Jun 11, 2016):

+1

@hmillet commented on GitHub (Jun 11, 2016): +1
Author
Owner

@daniel-adlantic commented on GitHub (Jul 6, 2016):

+1
I'd be interested in a solution or fix for this too.
In XML config I'm trying this:

<join-column name="type" referenced-column-name="id" nullable="false">
    <options>
        <option name="default">1</option>
    </options>
</join-column>

However schema update is coming up with:

CHANGE type type TINYINT(3) UNSIGNED NOT NULL,

Where I would expect

CHANGE type type TINYINT(3) UNSIGNED NOT NULL DEFAULT '1',

Edit: Fix expected result default.

@daniel-adlantic commented on GitHub (Jul 6, 2016): +1 I'd be interested in a solution or fix for this too. In XML config I'm trying this: ``` xml <join-column name="type" referenced-column-name="id" nullable="false"> <options> <option name="default">1</option> </options> </join-column> ``` However schema update is coming up with: ``` sql CHANGE type type TINYINT(3) UNSIGNED NOT NULL, ``` Where I would expect ``` sql CHANGE type type TINYINT(3) UNSIGNED NOT NULL DEFAULT '1', ``` Edit: Fix expected result default.
Author
Owner

@smarcet commented on GitHub (Jul 6, 2016):

+1
yes this is particular usefull for legacy schemas, i had to tweak the BasicEntityPersister::prepareUpdateData method :/

@smarcet commented on GitHub (Jul 6, 2016): +1 yes this is particular usefull for legacy schemas, i had to tweak the BasicEntityPersister::prepareUpdateData method :/
Author
Owner

@Ocramius commented on GitHub (Jul 6, 2016):

This is semantically incorrect, and will also break the ORM.

  1. it is semantically incorrect because... read here. I won't c&p it in the thread, but NULL is NULL, it's not 0, 1, "potato" or your legacy system's understanding of what NULL actually is.
  2. the ORM would break there, because a NULL association doesn't get hydrated into a proxy, while a non-null one will be turned into a proxy, and then your lazy-loading would crash.
  3. ORM and DB would be out of sync after an INSERT operation, causing potential FK integrity issues when managed freshly inserted entities with default DB-side attributes are not refreshed after a successful flush() operation. The ORM will assume that the inserted values are the real ones, while the DB actually changed them internally, automatically.

Therefore, default values in associations or fields do not make sense in ORM context. Please customize your DDL in a migration file, instead of pushing this responsibility down to the ORM mapping tools.

@Ocramius commented on GitHub (Jul 6, 2016): This is semantically incorrect, and will also break the ORM. 1. it is semantically incorrect because... [read here](http://stackoverflow.com/a/15511715/347063). I won't c&p it in the thread, but `NULL` is `NULL`, it's not `0`, `1`, `"potato"` or your legacy system's understanding of what `NULL` actually is. 2. the ORM would break there, because a `NULL` association doesn't get hydrated into a proxy, while a non-null one will be turned into a proxy, and then your lazy-loading would crash. 3. ORM and DB would be out of sync after an `INSERT` operation, causing potential FK integrity issues when managed freshly inserted entities with default DB-side attributes are not refreshed after a successful `flush()` operation. The ORM will assume that the inserted values are the real ones, while the DB actually changed them internally, automatically. Therefore, default values in associations or fields do not make sense in ORM context. Please customize your DDL in a migration file, instead of pushing this responsibility down to the ORM mapping tools.
Author
Owner

@daniel-adlantic commented on GitHub (Jul 7, 2016):

I agree, NULL is NULL. I'm not looking to substitute NULL with another value like 0 or 1. My default value 1 would be a reference to the associated table where there must be a row with identifier 1. I'd expect the system to crash if the referenced record does not exist.

@daniel-adlantic commented on GitHub (Jul 7, 2016): I agree, `NULL` is `NULL`. I'm not looking to substitute `NULL` with another value like `0` or `1`. My default value `1` would be a reference to the associated table where there must be a row with identifier `1`. I'd expect the system to crash if the referenced record does not exist.
Author
Owner

@Ocramius commented on GitHub (Jul 7, 2016):

Note that setting a default association value still wouldn't work due to
reasons I explained above
On 7 Jul 2016 10:48 a.m., "daniel-adlantic" notifications@github.com
wrote:

I agree, NULL is NULL. I'm not looking to substitute NULL with another
value like 0 or 1. My default value 1 would be a reference to the
associated table where there must be a row with identifier 1. I'd expect
the system to crash if the referenced record does not exist.


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/4638#issuecomment-231019865,
or mute the thread
https://github.com/notifications/unsubscribe/AAJakIMrhe0dDtKgVeC6DX7rHkkT4RVyks5qTL17gaJpZM4IX4rN
.

@Ocramius commented on GitHub (Jul 7, 2016): Note that setting a default association value still wouldn't work due to reasons I explained above On 7 Jul 2016 10:48 a.m., "daniel-adlantic" notifications@github.com wrote: > I agree, NULL is NULL. I'm not looking to substitute NULL with another > value like 0 or 1. My default value 1 would be a reference to the > associated table where there must be a row with identifier 1. I'd expect > the system to crash if the referenced record does not exist. > > — > You are receiving this because you modified the open/close state. > Reply to this email directly, view it on GitHub > https://github.com/doctrine/doctrine2/issues/4638#issuecomment-231019865, > or mute the thread > https://github.com/notifications/unsubscribe/AAJakIMrhe0dDtKgVeC6DX7rHkkT4RVyks5qTL17gaJpZM4IX4rN > .
Author
Owner

@smarcet commented on GitHub (Jul 7, 2016):

i understand that, but i am tied to a MYSQL schema defined on that way, BC i am using and accesing aThird party Silverstripe DB that is defined on that way, so i cant change the MYSQL schema sadly
https://docs.silverstripe.org/en/3.2/developer_guides/model/data_model_and_orm/
cheers

@smarcet commented on GitHub (Jul 7, 2016): i understand that, but i am tied to a MYSQL schema defined on that way, BC i am using and accesing aThird party Silverstripe DB that is defined on that way, so i cant change the MYSQL schema sadly https://docs.silverstripe.org/en/3.2/developer_guides/model/data_model_and_orm/ cheers
Author
Owner

@Ocramius commented on GitHub (Jul 7, 2016):

A couple things:

  1. use doctrine/migrations to define the schema: not the raw schema tool from DBAL+ORM.
  2. ping someone at @silverstripe (maybe @assertchris?) to look into it
  3. use default values at your own risk.
@Ocramius commented on GitHub (Jul 7, 2016): A couple things: 1. use [`doctrine/migrations`](https://github.com/doctrine/migrations) to define the schema: not the raw schema tool from DBAL+ORM. 2. ping someone at @silverstripe (maybe @assertchris?) to look into it 3. use default values at your own risk.
Author
Owner

@FaizRasool commented on GitHub (Aug 15, 2019):

Thats how i fixed it

/**
    * @var TimeZone
    *
    * @ORM\ManyToOne(targetEntity="TimeZone")
    * @ORM\JoinColumns({
    *   @ORM\JoinColumn(name="time_zone_id", referencedColumnName="id",columnDefinition="INT NOT NULL DEFAULT 342")
    * })
    */
   private $timeZone;
@FaizRasool commented on GitHub (Aug 15, 2019): Thats how i fixed it ``` /** * @var TimeZone * * @ORM\ManyToOne(targetEntity="TimeZone") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="time_zone_id", referencedColumnName="id",columnDefinition="INT NOT NULL DEFAULT 342") * }) */ private $timeZone; ```
Author
Owner

@duzenko commented on GitHub (Sep 23, 2022):

columnDefinition did nothing for me, same integrity constraint violation

@duzenko commented on GitHub (Sep 23, 2022): `columnDefinition` did nothing for me, same integrity constraint violation
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#4649