Invalid discriminator maps should be detected during schema/mapping validation #5607

Closed
opened 2026-01-22 15:12:32 +01:00 by admin · 8 comments
Owner

Originally created by @jeroenvrooij on GitHub (Jul 18, 2017).

Originally assigned to: @Ocramius on GitHub.

Given the following structure of entities, which are discriminated over two levels, fetching a Developer using the repository from the root entity (Person) results in exceptions.

doctrine2

The issue is that an Employee object is being instantiated, which fails since that class is abstract. So it seems that Doctrine is not following the tree until the leaf nodes. Fetching the Developer using the repository from it's direct parent (so the Employee) works fine.

This may, or may not, give some insights as well:
Persisting a Developer works ok, except that the order of insert queries executed are wrong (in my opinion). The Person is inserted first, followed by the Developer and the Employee is inserted last. (So: root -> leaf -> 2nd layer). This forces us to not have foreign keys on the id columns of the Employee, Staff and Developer.

Note:
I will submit some test cases which test the two scenarios of fetching using the different repositories.

Edit:
PR with the test case: https://github.com/doctrine/doctrine2/pull/6559

Originally created by @jeroenvrooij on GitHub (Jul 18, 2017). Originally assigned to: @Ocramius on GitHub. Given the following structure of entities, which are discriminated over two levels, fetching a _Developer_ using the repository from the root entity (_Person_) results in exceptions. ![doctrine2](https://user-images.githubusercontent.com/1611240/28304048-4a281060-6b96-11e7-8355-106df4a563c6.png) The issue is that an _Employee_ object is being instantiated, which fails since that class is abstract. So it seems that Doctrine is not following the tree until the leaf nodes. Fetching the _Developer_ using the repository from it's direct parent (so the _Employee_) works fine. This may, or may not, give some insights as well: Persisting a _Developer_ works ok, except that the order of insert queries executed are wrong (in my opinion). The _Person_ is inserted first, followed by the _Developer_ and the _Employee_ is inserted last. (So: root -> leaf -> 2nd layer). This forces us to not have foreign keys on the id columns of the _Employee_, _Staff_ and _Developer_. Note: I will submit some test cases which test the two scenarios of fetching using the different repositories. Edit: PR with the test case: https://github.com/doctrine/doctrine2/pull/6559
admin added the Bug label 2026-01-22 15:12:32 +01:00
admin closed this issue 2026-01-22 15:12:34 +01:00
Author
Owner

@Ocramius commented on GitHub (Jul 18, 2017):

Closing as invalid as per https://github.com/doctrine/doctrine2/pull/6559#issuecomment-316231681

The issue is that the schema validation tools didn't discover a duplicate inheritance definition, but that's for a separate issue to fix.

@Ocramius commented on GitHub (Jul 18, 2017): Closing as `invalid` as per https://github.com/doctrine/doctrine2/pull/6559#issuecomment-316231681 The issue is that the schema validation tools didn't discover a duplicate inheritance definition, but that's for a separate issue to fix.
Author
Owner

@jeroenvrooij commented on GitHub (Jul 19, 2017):

Could you please go in to a bit more detail? Because at the moment I do not understand if I made a mistake in the inheritance mapping or that multilevel discrimination is not even supported in the first place.
We also tried having the same structure of entities, but only have to inheritance mapping on the top level like you said. But that leads to different errors: during the fetching of a Developer the Employee properties would not get populated.

@jeroenvrooij commented on GitHub (Jul 19, 2017): Could you please go in to a bit more detail? Because at the moment I do not understand if I made a mistake in the inheritance mapping or that multilevel discrimination is not even supported in the first place. We also tried having the same structure of entities, but only have to inheritance mapping on the top level like you said. But that leads to different errors: during the fetching of a _Developer_ the _Employee_ properties would not get populated.
Author
Owner

@Ocramius commented on GitHub (Jul 21, 2017):

You basically need to define the inheritance mapping only at the very top of the inheritance.

@Ocramius commented on GitHub (Jul 21, 2017): You basically need to define the inheritance mapping only at the very top of the inheritance.
Author
Owner

@jeroenvrooij commented on GitHub (Jul 24, 2017):

Yeah I get that. But like I said, that is also not a valid mapping. We tried that as well. Please check this PR with the updated test case which hopefully clears things up :). https://github.com/doctrine/doctrine2/pull/6578

@jeroenvrooij commented on GitHub (Jul 24, 2017): Yeah I get that. But like I said, that is also not a valid mapping. We tried that as well. Please check this PR with the updated test case which hopefully clears things up :). https://github.com/doctrine/doctrine2/pull/6578
Author
Owner

@Ocramius commented on GitHub (Jul 24, 2017):

@jeroenvrooij re-opening then, thanks for clarifying with a new test case 👍

@Ocramius commented on GitHub (Jul 24, 2017): @jeroenvrooij re-opening then, thanks for clarifying with a new test case :+1:
Author
Owner

@Ocramius commented on GitHub (Aug 19, 2017):

As discussed in https://github.com/doctrine/doctrine2/pull/6578#issuecomment-321496030, this issue is a schema validator problem: some discriminator values are missing in the discriminator map.

@Ocramius commented on GitHub (Aug 19, 2017): As discussed in https://github.com/doctrine/doctrine2/pull/6578#issuecomment-321496030, this issue is a schema validator problem: some discriminator values are missing in the discriminator map.
Author
Owner

@mstefan21 commented on GitHub (Oct 18, 2017):

HI, i have a same problem with multiple inheritance, but i had different discriminator column names. It's ok? or i must have same discriminator column name?

Our structure is same as image, but i in Image is discriminator column name "PersonType" and in Employee is discriminator column name is "EmployeeType", if i call findAll() on Person, i get only Managers and Employes and doctrine not resolve Epmployees inheritance.

@mstefan21 commented on GitHub (Oct 18, 2017): HI, i have a same problem with multiple inheritance, but i had different discriminator column names. It's ok? or i must have same discriminator column name? Our structure is same as image, but i in Image is discriminator column name "PersonType" and in Employee is discriminator column name is "EmployeeType", if i call findAll() on Person, i get only Managers and Employes and doctrine not resolve Epmployees inheritance.
Author
Owner

@przemyslaw-leczycki-valueadd commented on GitHub (Nov 30, 2017):

Hi @Ocramius I've got related problem to this.
My entity structure is

Item -> Document
        Deviation
        Media -> Image
                 ...

I've got discriminators specified in Item class.
Item is an abstract class as well as Media.

If I use $mediaRepository->find($id) everything works fine

SELECT t1.name AS name_3, t1.deleted_at AS deleted_at_4, t1.id AS id_5, t1.created_at AS created_at_6, t1.updated_at AS updated_at_7, t0.description AS description_8, t0.photographer AS photographer_9, t0.expired AS expired_10, t0.filePath_path AS filePath_path_11, t1.folder_id AS folder_id_12, t1.site_id AS site_id_13, t1.archived_by_id AS archived_by_id_14, t1.created_by_id AS created_by_id_15, t1.updated_by_id AS updated_by_id_16, t1.type, t2.zoom_level AS zoom_level_17, t2.position_y AS position_y_18, t2.position_x AS position_x_19, t2.rotation_value AS rotation_value_20 
FROM items_media t0 
INNER JOIN items t1 ON t0.id = t1.id 
LEFT JOIN items_media_type_image t2 
ON t0.id = t2.id 
WHERE t1.id = ? AND ((t1.deleted_at IS NULL) AND (t1.site_id = 'DE09FACA-7210-11E7-8CF7-A6006AD3DBA0') AND (t1.deleted_at IS NULL))

if I use $itemRepository->find($id) none of the values from Media Entity are populated to leaf entity.

SELECT t0.name AS name_4, t0.deleted_at AS deleted_at_5, t0.id AS id_6, t0.created_at AS created_at_7, t0.updated_at AS updated_at_8, t0.folder_id AS folder_id_9, t0.site_id AS site_id_10, t0.archived_by_id AS archived_by_id_11, t0.created_by_id AS created_by_id_12, t0.updated_by_id AS updated_by_id_13, t0.type, t1.description AS description_14, t1.numeric_identifier AS numeric_identifier_15, t1.status_status AS status_status_16, t2.numeric_identifier AS numeric_identifier_17, t2.status_status AS status_status_18, t2.impacts_impacts_health AS impacts_impacts_health_19, t2.impacts_impacts_environment AS impacts_impacts_environment_20, t2.impacts_impacts_safety AS impacts_impacts_safety_21, t2.impacts_impacts_quality AS impacts_impacts_quality_22, t3.zoom_level AS zoom_level_23, t3.position_y AS position_y_24, t3.position_x AS position_x_25, t3.rotation_value AS rotation_value_26 
FROM items t0 
LEFT JOIN items_documents t1 ON t0.id = t1.id 
LEFT JOIN items_deviations t2 ON t0.id = t2.id 
LEFT JOIN items_media_type_image t3 ON t0.id = t3.id 
WHERE t0.id = ? AND ((t0.deleted_at IS NULL) AND (t0.site_id = 'DE09FACA-7210-11E7-8CF7-A6006AD3DBA0') AND (t0.deleted_at IS NULL))

As you see on attached SQL dumps in second example doctrine didn't join items_media table at all which cause all properties from Media Entity that should be in Image Entity are null or empty string.
I saw it's reproduced in PR #6578 method testEmployeeIsPopulated().
I didn't find explicitly related issue to this. Should I create new one or it's related to this issue?

@przemyslaw-leczycki-valueadd commented on GitHub (Nov 30, 2017): Hi @Ocramius I've got related problem to this. My entity structure is ``` Item -> Document Deviation Media -> Image ... ``` I've got discriminators specified in Item class. Item is an abstract class as well as Media. If I use `$mediaRepository->find($id)` everything works fine ``` SELECT t1.name AS name_3, t1.deleted_at AS deleted_at_4, t1.id AS id_5, t1.created_at AS created_at_6, t1.updated_at AS updated_at_7, t0.description AS description_8, t0.photographer AS photographer_9, t0.expired AS expired_10, t0.filePath_path AS filePath_path_11, t1.folder_id AS folder_id_12, t1.site_id AS site_id_13, t1.archived_by_id AS archived_by_id_14, t1.created_by_id AS created_by_id_15, t1.updated_by_id AS updated_by_id_16, t1.type, t2.zoom_level AS zoom_level_17, t2.position_y AS position_y_18, t2.position_x AS position_x_19, t2.rotation_value AS rotation_value_20 FROM items_media t0 INNER JOIN items t1 ON t0.id = t1.id LEFT JOIN items_media_type_image t2 ON t0.id = t2.id WHERE t1.id = ? AND ((t1.deleted_at IS NULL) AND (t1.site_id = 'DE09FACA-7210-11E7-8CF7-A6006AD3DBA0') AND (t1.deleted_at IS NULL)) ``` if I use `$itemRepository->find($id)` none of the values from Media Entity are populated to leaf entity. ``` SELECT t0.name AS name_4, t0.deleted_at AS deleted_at_5, t0.id AS id_6, t0.created_at AS created_at_7, t0.updated_at AS updated_at_8, t0.folder_id AS folder_id_9, t0.site_id AS site_id_10, t0.archived_by_id AS archived_by_id_11, t0.created_by_id AS created_by_id_12, t0.updated_by_id AS updated_by_id_13, t0.type, t1.description AS description_14, t1.numeric_identifier AS numeric_identifier_15, t1.status_status AS status_status_16, t2.numeric_identifier AS numeric_identifier_17, t2.status_status AS status_status_18, t2.impacts_impacts_health AS impacts_impacts_health_19, t2.impacts_impacts_environment AS impacts_impacts_environment_20, t2.impacts_impacts_safety AS impacts_impacts_safety_21, t2.impacts_impacts_quality AS impacts_impacts_quality_22, t3.zoom_level AS zoom_level_23, t3.position_y AS position_y_24, t3.position_x AS position_x_25, t3.rotation_value AS rotation_value_26 FROM items t0 LEFT JOIN items_documents t1 ON t0.id = t1.id LEFT JOIN items_deviations t2 ON t0.id = t2.id LEFT JOIN items_media_type_image t3 ON t0.id = t3.id WHERE t0.id = ? AND ((t0.deleted_at IS NULL) AND (t0.site_id = 'DE09FACA-7210-11E7-8CF7-A6006AD3DBA0') AND (t0.deleted_at IS NULL)) ``` As you see on attached SQL dumps in second example doctrine didn't join items_media table at all which cause all properties from **Media** Entity that should be in **Image** Entity are null or empty string. I saw it's reproduced in PR #6578 method `testEmployeeIsPopulated()`. I didn't find explicitly related issue to this. Should I create new one or it's related to this issue?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5607