I don't think that the DTYPE in (...) is caused by your treat but because you are querying a single table inheritance class in general. I think Hibernate adds all subtypes it knows of into the in-items. IMO according to JPA spec 3.10.15 Polymorphic Queries Hibernate must in that case always produce such a predicate. IMO the problem is that 4.4.9 Downcasting doesn't specifically say if subtype filtering should be applied when treat is used in the WHERE clause. I think we can agree that in the FROM clause it's clear that it must filter, but filtering subtypes when using treat in any clause other than FROM, would violate 3.10.15 and IMO also not be a good idea. I have tried to sum up my whole interpretation of the treat operator here, hope that helps you: https://github.com/beikov/jpa-treat-variations According to the optimization O1 from my readme(and actually also JPA 3.10.15 and JPA 4.4.8), you should be able to achieve what you want if you rewrite the query to
select generatedAlias0 from BaseType as generatedAlias0 where
( ( type(generatedAlias0) = org.hibernate.bugs.SubType1 )
and ( generatedAlias0.basevalue=100 )
and ( treat(generatedAlias0 as org.hibernate.bugs.SubType1).subvalue1 is null ) ) or
( ( type(generatedAlias0) = org.hibernate.bugs.SubType2 )
and ( generatedAlias0.basevalue=200 )
and ( treat(generatedAlias0 as org.hibernate.bugs.SubType2).subvalue2 is null ) )
Now if you had a third subtype e.g. "SubType3" then Hibernate will probably also query for SubType3. This is where the optimization O3 should kick in, which should eliminate the SubType3 from the in-items. |