Relates to #2002, #2015.
| Q | A
|------------ | ------
| BC Break | no
| Version | dev-master
I followed @malarzm comment about not needing to query by discriminator field and removed the query. And it worked well. But today, as I tested the fixed #2002 and removed the discriminator map (falling back to class name which best suits my needs) the query started returning the parent classes.
I am not sure if it is expected or a bug.
/**
* NO DISCRIMINATOR MAP
*/
class A {
}
class B extends A {
}
$results = $dm->createQueryBuilder(B::class)->find()->...
$results contains instance of A amongst B's.
This was initially fixed in #1962 but reverted in #1978 due to a regression (see #1970). I had this on my radar for 2.0 but lost track of it. I'll be providing a fix shortly.
So this use-case is a bit different (and unfortunately significantly more complicated) than the original issue in #1962. For a bit of knowledge about internals, when you define a discriminator map on a document, you're basically telling ODM that there are child classes of this class that contain mapping information. ODM will not immediately load these, but it will know of them. This information is then used when you query for a class that has child classes: we go through the list of child classes and add all their discriminator values to the query. Reason why we had to revert the fix in 1.x was because you could have incomplete discriminator maps, e.g. tell ODM about some subclasses, but not all of them. Obviously, the fix breaks existing behaviour (since querying always returned all documents and suddenly only returned a subset of them).
However, when not using discriminator maps, we don't know if a class has any child classes: we'd have to autoload pretty much everything, see if it extends our class and then check if it has mapping information. Obviously, that would be a tremendous performance killer, which is why we don't do this. Unfortunately, this means that when using inheritance without discriminator maps, we can't limit the results at all, as all we could limit it to would be the current class. Thus, if you have a complex inheritance chain (as demonstrated in the test for #1962), you will not be able to query for subclasses only as we don't know what your subclasses' discriminator values are. Since you can extend a mapped superclass or a document, we can't also use the mapping type to determine whether a given class is a leaf. You can work around this by marking your leaf documents with an @DiscriminatorValue annotation, but we can't properly limit the documents returned if you query for a parent class that is a child class itself.
What this means is: if you are using discriminator maps, the upcoming PR will fix querying, as #1962 did. If you don't use discriminator maps, the behaviour will remain the same as it is in 1.x: querying for a document that does not have a discriminator value will not limit the results in any way. The solution above with @DiscriminatorValue will work around that issue.
TL;DR provided by @malarzm:
no discriminator maps = no fancy features
no discriminator maps = no fancy features
LOL. Yeah sure, as long as it is well documented ;-)
Closing as #2025 was merged.
Most helpful comment
So this use-case is a bit different (and unfortunately significantly more complicated) than the original issue in #1962. For a bit of knowledge about internals, when you define a discriminator map on a document, you're basically telling ODM that there are child classes of this class that contain mapping information. ODM will not immediately load these, but it will know of them. This information is then used when you query for a class that has child classes: we go through the list of child classes and add all their discriminator values to the query. Reason why we had to revert the fix in 1.x was because you could have incomplete discriminator maps, e.g. tell ODM about some subclasses, but not all of them. Obviously, the fix breaks existing behaviour (since querying always returned all documents and suddenly only returned a subset of them).
However, when not using discriminator maps, we don't know if a class has any child classes: we'd have to autoload pretty much everything, see if it extends our class and then check if it has mapping information. Obviously, that would be a tremendous performance killer, which is why we don't do this. Unfortunately, this means that when using inheritance without discriminator maps, we can't limit the results at all, as all we could limit it to would be the current class. Thus, if you have a complex inheritance chain (as demonstrated in the test for #1962), you will not be able to query for subclasses only as we don't know what your subclasses' discriminator values are. Since you can extend a mapped superclass or a document, we can't also use the mapping type to determine whether a given class is a leaf. You can work around this by marking your leaf documents with an
@DiscriminatorValueannotation, but we can't properly limit the documents returned if you query for a parent class that is a child class itself.What this means is: if you are using discriminator maps, the upcoming PR will fix querying, as #1962 did. If you don't use discriminator maps, the behaviour will remain the same as it is in 1.x: querying for a document that does not have a discriminator value will not limit the results in any way. The solution above with
@DiscriminatorValuewill work around that issue.TL;DR provided by @malarzm: