-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check if the discriminator value is null
before converting it and setting into rowData
during hydration
#6304
Conversation
Needs tests
…On 24 Feb 2017 7:30 p.m., "fullbl" ***@***.***> wrote:
fixes #6303 <#6303>
------------------------------
You can view, comment on, or merge this pull request online at:
#6304
Commit Summary
- check if value is null before converting it and setting into rowData
File Changes
- *M* lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
<https://github.com/doctrine/doctrine2/pull/6304/files#diff-0> (8)
Patch Links:
- https://github.com/doctrine/doctrine2/pull/6304.patch
- https://github.com/doctrine/doctrine2/pull/6304.diff
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#6304>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAJakEit5cOVeTTHSLfvACICMkc5yCJBks5rfyHYgaJpZM4MLh1s>
.
|
Tests added, but seems that my edit broke a lot of other tests... Checking for non empty values instead of isset seems to fix things, but this solution is dipendent on the default value of SimpleArray. |
@@ -10,6 +10,7 @@ | |||
* @DiscriminatorMap({ | |||
* "person" = "Issue5989Person", | |||
* "manager" = "Issue5989Manager", | |||
* "secretary" = "Issue5989Secretary", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use a different entity and a new inheritance tree to test your specific scenario
@@ -290,10 +290,10 @@ protected function gatherRowData(array $data, array &$id, array &$nonemptyCompon | |||
// in an inheritance hierarchy the same field could be defined several times. | |||
// We overwrite this value so long we don't have a non-null value, that value we keep. | |||
// Per definition it cannot be that a field is defined several times and has several values. | |||
if (isset($rowData['data'][$dqlAlias][$fieldName])) { | |||
if (!empty($rowData['data'][$dqlAlias][$fieldName])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment above explicitly references "non-null" values
$secretary = new Issue5989Secretary(); | ||
|
||
$secretaryTags = 'single_tag'; | ||
$secretary->tags = $secretaryTags; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that you use a different type for a property in the inheritance tree is quite confusing: is this intentional?
|
||
static::assertEquals($tags[$people[0]->id], $people[0]->tags); | ||
static::assertEquals($tags[$people[1]->id], $people[1]->tags); | ||
static::assertEquals($tags[$people[2]->id], $people[2]->tags); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which of these assertions would fail without your patch in place?
@@ -290,10 +290,10 @@ protected function gatherRowData(array $data, array &$id, array &$nonemptyCompon | |||
// in an inheritance hierarchy the same field could be defined several times. | |||
// We overwrite this value so long we don't have a non-null value, that value we keep. | |||
// Per definition it cannot be that a field is defined several times and has several values. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This particular definition is what is being challenged by your inheritance design. The field definition should be fetched per entity name, and $fieldName
should be specific to the currently hydrated entity type instead of just the name of a field. Did you try step-debugging here? What is $type
?
Hi, I will create new entities as soon as possible, I thought it would be good to reuse the old ones! $type is StringType for string and SimpleArrayType for simple array, so is different based on the field. The problem is exactly as you stated in
This is what is breaking stuff. The failing assertion is the one for the string field. It's hydrated by the simple_array as an empty array and missing the real value. To be honest, I'm not satisfied with my solution, I will think about it in next days! |
Hi again, I fixed the tests to use their own inheritance, but I removed my fix, because I would like to add more tests for checking that setting some property to false, 0 or empty array should return correct values! |
Here we are, I added those tests and decided to redo the fix in another way, keeping only values from the correct table! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also fix the coding style to match with rest of the project, please?
* "contract_a" = "DDC6303ContractA" | ||
* }) | ||
*/ | ||
class DDC6303Contract |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this class together with the test class (same file)
* @Entity | ||
* @Table(name="ddc6303_contracts_a") | ||
*/ | ||
class DDC6303ContractA extends DDC6303Contract |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this class together with the test class (same file)
* @Entity | ||
* @Table(name="ddc6303_contracts_b") | ||
*/ | ||
class DDC6303ContractB extends DDC6303Contract |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this class together with the test class (same file)
{ | ||
public function setUp() | ||
{ | ||
$this->useModelSet('ddc6303'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialise the schema here instead of using a model set
@@ -302,6 +302,12 @@ | |||
Models\Issue5989\Issue5989Employee::class, | |||
Models\Issue5989\Issue5989Manager::class, | |||
], | |||
'ddc6303' => [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed when models are in the test file
// in an inheritance hierarchy the same field could be defined several times. | ||
// We overwrite this value so long we don't have a non-null value, that value we keep. | ||
// Per definition it cannot be that a field is defined several times and has several values. | ||
if (isset($rowData['data'][$dqlAlias][$fieldName])) { | ||
break; | ||
} | ||
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the trailing spaces
]; | ||
if( !empty($classMetadata->parentClasses && isset($this->_rsm->discriminatorColumns[$ownerMap]))){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really the expression we're looking for? It looks like it should be:
if ( ! empty($classMetadata->parentClasses) && isset($this->_rsm->discriminatorColumns[$ownerMap])) {
}
Done, I made it first into different files because I copypasted from another issue, maybe it was old! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Patch looks good to me! The rest are nitpicks and improvements that can be done on merge.
if( | ||
isset($cacheKeyInfo['discriminatorColumn']) && | ||
isset($data[$cacheKeyInfo['discriminatorColumn']]) && | ||
$data[$cacheKeyInfo['discriminatorColumn']] != $cacheKeyInfo['discriminatorValue'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be !==
to avoid type juggling hell. Yes, that means that object discriminators will fail, that's an edge case that the ORM doesn't handle anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems to me that this change is breaking another test (/code/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php:179). Is it ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fullbl it shouldn't break it... let's keep the strict comparison and try to find the root cause.
]; | ||
if( !empty($classMetadata->parentClasses) && isset($this->_rsm->discriminatorColumns[$ownerMap])){ | ||
$returnArray += [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider making two return
operations instead of using +=
$contractA->originalData = $contractAData; | ||
|
||
$contractB = new DDC6303ContractB(); | ||
$contractBData = ['accepted', 'authorized']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add comments for the reader, specifying that these two entities map originalData
differently?
null
before converting it and setting into rowData
during hydration
@fullbl I rebased this branch on top of
|
I checked the issue locally, and it's because the discriminator is not converted to a PHP value. That said, trying to fix the issue leads to a massive can of worms that is being opened: let's keep the loose comparison there for now. |
… (which is bullshit), so we use `array` here
…/JTI require additional information and checks in the hydration process
- `em` protected property - annotation namespace change - `QueryBuilder` instantiation
…es in `3.x` - `em` protected property - annotation namespace change - `QueryBuilder` instantiation
fixes #6303