Composite key override pre generated id value #6497

Closed
opened 2026-01-22 15:34:06 +01:00 by admin · 4 comments
Owner

Originally created by @mathroc on GitHub (Jul 6, 2020).

Bug Report

Q A
BC Break no
Version 2.7.2

Summary

I have a one-to-many relation between a freelance and its organizations and a one-to-one between a freelance and one of its organizations (to define the default one)

freelance ids are pre generated (uuid) but organization ids are not (postgres sequence)

when trying to insert a new freelance I generate an uuid but it’s overridden in the BasicEntityPersister because of the defaultOrganization relation

here is part of the freelance mapping:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity repository-class="App\Infra\Repository\FreelanceRepositoryDoctrineAdapter" name="App\Domain\Model\Freelance" table="freelance">
    <unique-constraints>
      <unique-constraint name="defaultOrganization_uniq" columns="default_organization_id"/>
    </unique-constraints>
    <id name="id" type="uuid" column="id">
      <generator strategy="NONE"/>
    </id>
    <one-to-one field="defaultOrganization" target-entity="App\Domain\Model\Freelance\Organization">
      <join-columns>
        <join-column name="id" referenced-column-name="freelance_id"/>
        <join-column name="default_organization_id" referenced-column-name="organization_id"/>
      </join-columns>
    </one-to-one>
    <one-to-many field="freelanceOrganizations" target-entity="App\Domain\Model\Freelance\Organization" mapped-by="freelance">
      <cascade>
        <cascade-persist/>
        <cascade-remove/>
      </cascade>
      <order-by>
        <order-by-field name="position"/>
      </order-by>
    </one-to-many>
  </entity>
</doctrine-mapping>

other findings

I’m not sure why but $newVal is null for the defaultOrganization field in BasicEntityPersister::prepareUpdateData() this causes all of the field join column field to be null’ed

I don’t know if the BasicEntityPersister should just avoid overriding an existing non-null field with null or if it’s because $newVal should not be null in the first place

maybe related to #8141

Originally created by @mathroc on GitHub (Jul 6, 2020). ### Bug Report | Q | A |------------ | ------ | BC Break | no | Version | 2.7.2 #### Summary I have a one-to-many relation between a freelance and its organizations and a one-to-one between a freelance and one of its organizations (to define the default one) freelance ids are pre generated (uuid) but organization ids are not (postgres sequence) when trying to insert a new freelance I generate an uuid but it’s overridden in the `BasicEntityPersister` because of the defaultOrganization relation here is part of the freelance mapping: ```xml <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity repository-class="App\Infra\Repository\FreelanceRepositoryDoctrineAdapter" name="App\Domain\Model\Freelance" table="freelance"> <unique-constraints> <unique-constraint name="defaultOrganization_uniq" columns="default_organization_id"/> </unique-constraints> <id name="id" type="uuid" column="id"> <generator strategy="NONE"/> </id> <one-to-one field="defaultOrganization" target-entity="App\Domain\Model\Freelance\Organization"> <join-columns> <join-column name="id" referenced-column-name="freelance_id"/> <join-column name="default_organization_id" referenced-column-name="organization_id"/> </join-columns> </one-to-one> <one-to-many field="freelanceOrganizations" target-entity="App\Domain\Model\Freelance\Organization" mapped-by="freelance"> <cascade> <cascade-persist/> <cascade-remove/> </cascade> <order-by> <order-by-field name="position"/> </order-by> </one-to-many> </entity> </doctrine-mapping> ``` # other findings I’m not sure why but `$newVal` is `null` for the `defaultOrganization` field in `BasicEntityPersister::prepareUpdateData()` this causes all of the field join column field to be null’ed I don’t know if the `BasicEntityPersister` should just avoid overriding an existing non-null field with null or if it’s because `$newVal` should not be null in the first place maybe related to #8141
admin closed this issue 2026-01-22 15:34:06 +01:00
Author
Owner

@mathroc commented on GitHub (Jul 6, 2020):

I found out that $newVal is not null at the start of the loop but this piece of code makes it null : https://github.com/doctrine/orm/blob/2.7/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php#L652-L661

at the very least existing values should not be overridden and that would be enough to fix my issue

my guess is that the end goal should be to compute $newValId even if the target entity is not persisted yet, then, if the column is non nullable it should be set in $result (to handle deferred foreign key)

@mathroc commented on GitHub (Jul 6, 2020): I found out that `$newVal` is not `null` at the start of the loop but this piece of code makes it `null` : https://github.com/doctrine/orm/blob/2.7/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php#L652-L661 at the very least existing values should not be overridden and that would be enough to fix my issue my guess is that the end goal should be to compute `$newValId` even if the target entity is not persisted yet, then, if the column is non nullable it should be set in `$result` (to handle deferred foreign key)
Author
Owner

@beberlei commented on GitHub (Jul 6, 2020):

This mapping is invalid, you cannot define the same column twice.

@beberlei commented on GitHub (Jul 6, 2020): This mapping is invalid, you cannot define the same column twice.
Author
Owner

@mathroc commented on GitHub (Jul 6, 2020):

doctrine:schema:validate says:

[OK] The mapping files are correct.

should I open another issue for this ?


and, is there a way to fix this mapping ?

I could add an id to App\Domain\Model\Freelance\Organization and use this instead of the composite key, but having the primary key inside the composite key makes it impossible to set an organization from another freelance the default organization

@mathroc commented on GitHub (Jul 6, 2020): `doctrine:schema:validate` says: > [OK] The mapping files are correct. should I open another issue for this ? --- and, is there a way to fix this mapping ? I could add an id to `App\Domain\Model\Freelance\Organization` and use this instead of the composite key, but having the primary key inside the composite key makes it impossible to set an organization from another freelance the default organization
Author
Owner

@mathroc commented on GitHub (Aug 17, 2020):

ping @beberlei

@mathroc commented on GitHub (Aug 17, 2020): ping @beberlei
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6497