-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Unknown
-
None
-
Affects Version/s: None
-
Component/s: Query
-
None
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Summary
Hibernate ORM narrows treat(... as ...) over a single table by way of an inline view whose name
is a SQL select. That name reaches the aggregate command unchanged, so the command names a
collection that cannot exist. Querying a nonexistent collection is not an error in MongoDB, it
matches nothing, so the query returns an empty result with no indication that anything went wrong.
Separately, when treat appears in the where clause the emitted $match carries no
discriminator restriction, so the query matches rows of sibling subtypes.
Reproducer
@Entity(name = "Vehicle") @Table(name = "vehicles") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "kind", discriminatorType = DiscriminatorType.STRING) static class Vehicle { @Id int id; String name; } @Entity(name = "Car") @DiscriminatorValue("CAR") static class Car extends Vehicle { int doors; }
Two rows in vehicles: a CAR named "saloon" with 4 doors, and a BIKE named "quadracycle"
that also carries a doors value of 4. Only the discriminator distinguishes them.
treat in the select clause
select treat(v as Car).doors from Vehicle v
{"aggregate": "(select * from vehicles t where t.kind='CAR')",
"pipeline": [{"$project": {"doors": true}}]}
Returns no rows. select treat(v as Car) from Vehicle v behaves the same way.
treat in the where clause
select v.name from Vehicle v where treat(v as Car).doors = 4
{"aggregate": "vehicles",
"pipeline": [{"$match": {"doors": {"$eq": 4}}}, {"$project": {"name": true}}]}
Returns ["saloon", "quadracycle"]. The bike is not a Car, so it should not match.
Proposed fix
Resolve the treated table reference back to the underlying collection, and render the discriminator
restriction into $match in both clause positions.
If a narrowing form cannot be translated, it has to fail with FeatureNotSupportedException
rather than run. Both failures here are silent, one returning too few rows and the other too many.
Acceptance
Selecting an attribute of a treated root, selecting the treated root itself, and filtering on an
attribute of a treated root each return exactly the rows of the named subtype, asserted by value.