[hibernate-dev] Treat support

Emond Papegaaij emond.papegaaij at topicus.nl
Tue Aug 23 08:31:02 EDT 2016


Hi Christian,

I don't think HHH-11062 is a bug in the Criteria to HQL/JPQL rendering. In the 
JPQL it renders as:

select treat(generatedAlias0 as org.hibernate.bugs.MyEntity) from MyEntity as 
generatedAlias0

Which seems ok to me, even though the treat is superfluous in this case.

Best regards,
Emond

On dinsdag 23 augustus 2016 14:08:20 CEST Christian Beikov wrote:
> Hi Emond,
> 
> thanks for the list, I already linked some of the issues you opened.
> HHH-10561, HHH-10759, HHH-10767 and HHH-11062 are apparently bugs in the
> Criteria to HQL/JPQL rendering and I am trying to directly target the
> HQL/JPQL parts.
> 
> Regarding HHH-10768 see the comments on the issue.
> 
> 
> Regards,
> 
> Christian
> 
> Am 23.08.2016 um 11:36 schrieb Emond Papegaaij:
> > Hi Christian,
> > 
> > In the past few months I've reported quite a few bugs on treat support in
> > Hibernate. I think some of them are already covered by your tests, but not
> > all. You might want to add those to your tests. These are the issues I've
> > reported:
> > https://hibernate.atlassian.net/browse/HHH-10561
> > https://hibernate.atlassian.net/browse/HHH-10759
> > https://hibernate.atlassian.net/browse/HHH-10767
> > https://hibernate.atlassian.net/browse/HHH-10768
> > https://hibernate.atlassian.net/browse/HHH-11062
> > 
> > Best regards,
> > Emond
> > 
> > On dinsdag 23 augustus 2016 11:07:22 CEST Christian Beikov wrote:
> >> Hi,
> >> 
> >> so I finished my work on the testsuite
> >> <https://github.com/beikov/jpa-treat-variations> for the treat operator.
> >> I also started a forum topic for this discussion:
> >> https://forum.hibernate.org/viewtopic.php?f=1&t=1043553
> >> If anyone is interested, I also started a discussion in the EclipeLink
> >> forum about that:
> >> https://www.eclipse.org/forums/index.php/mn/msg/1080319/1/on/0/?SQ=5ddc74
> >> f60 1d6750e4794121738a57076
> >> 
> >> I hope we can all agree on an interpretation of how treat should work
> >> and hopefully get a clarification into the spec. Or at least some TCK
> >> tests, as it doesn't seem to assert anything useful right now.
> >> 
> >> Regards,
> >> Christian
> >> 
> >> Am 09.08.2016 um 13:14 schrieb Christian Beikov:
> >>> Hello again,
> >>> 
> >>> I finished the first part of the test cases for root treats and
> >>> many-to-one treats. I also tried to explain how I would expect treat
> >>> to work and present a reduction/translation strategy to be able to
> >>> reduce thinking just about the base cases.
> >>> Could you comment on that?
> >>> https://github.com/beikov/jpa-treat-variations/blob/master/src/test/java
> >>> /j
> >>> pa/test/TreatVariationsTest.java The tests show various problems with
> >>> Hibernate as well as EclipseLink. I will add findings from Datanucleus
> >>> as
> >>> soon as the relation mapping for table per class is supported.
> >>> 
> >>> Here is a collection of JIRAs for treat problems
> >>> 
> >>>    * https://hibernate.atlassian.net/browse/HHH-10988
> >>>    * https://hibernate.atlassian.net/browse/HHH-9345
> >>>    * https://hibernate.atlassian.net/browse/HHH-9862
> >>>    * https://hibernate.atlassian.net/browse/HHH-10768
> >>>    * https://hibernate.atlassian.net/browse/HHH-9594
> >>> 
> >>> The definition of the semantics according to JPA spec 4.4.9 are a bit
> >>> strange as it does not distinguish between FROM and WHERE clause when
> >>> mentioning filtering on the subtype.
> >>> It specifically says "Use of the TREAT operator therefore also has the
> >>> effect of filtering on the specified type (and its subtypes) as well
> >>> as performing the downcast" and I think this is only relevant for
> >>> treats in the FROM clause.
> >>> Treats in the WHERE clause should not result in filtering. Depending
> >>> on the join type which is used for the treat path, the result of the
> >>> treat is either the subtype instance, or may be NULL in case of a left
> >>> join.
> >>> Since any comparison(except NULL aware operations) with NULL will
> >>> eventually result in FALSE according to the SQL spec, the requirement
> >>> for the treat operator in the WHERE clause to result in FALSE for
> >>> instances that are not a subtype is also fulfilled.
> >>> The section "... and in the case of a restriction, the associated
> >>> predicate is false." didn't consider NULL aware operations so I think
> >>> this is an oversight.
> >>> 
> >>> Am 04.08.2016 um 15:52 schrieb Steve Ebersole:
> >>>> Hey Christian,
> >>>> 
> >>>> In general terms, one of the items on the docket for SQM is better
> >>>> TREAT support; but there is a lot that goes into that statement.  One
> >>>> aspect is what we support in the parser properly in terms of
> >>>> recognition.  Another is how this translates into the generates SQL
> >>>> query.  All of this is being looked at with SQM.
> >>>> 
> >>>> Also, relatedly, better support for switching on/off JPQL-compliance
> >>>> checking is a goal.
> >>>> 
> >>>> <background>
> >>>> TREAT is an explicit downcast operator.  It allows you to down cast a
> >>>> type reference in order to reference one of its subclass attributes.
> >>>> HQL actually supports implicit downcasting (subclass attribute
> >>>> references).  In a way you can think of HQL as offering TREAT support
> >>>> implicitly.
> >>>> </background>
> >>>> 
> >>>> With all that in mind, see my comments inline...
> >>>> 
> >>>> 
> >>>> On Wed, Aug 3, 2016 at 9:43 PM Christian Beikov
> >>>> 
> >>>> <christian.beikov at gmail.com <mailto:christian.beikov at gmail.com>> wrote:
> >>>>        * Missing support for treated paths like "TREAT(...).property"
> >>>>      
> >>>>      in the
> >>>>      
> >>>>          parser. This is more or less workaroundable for non-root path
> >>>>          treats. Since root paths can't be treat joined to my
> >>>>      
> >>>>      knowledge, some
> >>>>      
> >>>>          treated paths simple can't be used. Maybe in 90% of the cases
> >>>>          hibernate will just resolve to the right property without
> >>>>          needing
> >>>>          the treat?
> >>>> 
> >>>> I'm not sure what you mean by "root paths can't be treated".  You
> >>>> mean literally the query root?  As in "MyEntity e" in "select e from
> >>>> MyEntity e"?  If so, yes JPA does not allow for that to be TREAT'ed;
> >>>> but really it makes no sense to allow TREAT there, if you step back
> >>>> and look at it.  A query like "select e from TREAT(MyEntity as MySub)
> >>>> e" makes no sense; its ultimately just the same as "select e from
> >>>> MySub e".  Arguably I guess it *could* make some sense *if* MySub is
> >>>> a sub MappedSuperclass since technically JPA also allows only
> >>>> entities as query roots (HQL does not have this restriction).
> >>>> 
> >>>> As discussed above, assuming that "someProp" is a persistent property
> >>>> defined on MySub, this is a perfectly valid HQL: "select e.someProp
> >>>> from MyEntity e".  It is not however valid JPQL; in JPQL you'd have
> >>>> to say: "select treat( e as MySub).someProp from MyEntity e"
> >>>> 
> >>>> All that said, the inability to dereference a TREAT'ed path (the
> >>>> ".property" part) would be a bug, and tbh I am surprised that you say
> >>>> this does not work with Hibernate. Which of your tests show this not
> >>>> working?  Is there a related Jira?
> >>>> 
> >>>>        * Missing support for a special case of treat join which
> >>>>        apparently
> >>>>        
> >>>>          was overseen by the JPA spec which would be
> >>>>      
> >>>>      "TREAT(TREAT(rootPath AS
> >>>>      
> >>>>          Subtype).relation AS RelationSubtype)". Eclipselink not only
> >>>>      
> >>>>      allows
> >>>>      
> >>>>          this syntax but for inner joins also implements the
> >>>>          appropriate
> >>>>          logic. I am thinking that this might even work in hibernate
> >>>>      
> >>>>      without
> >>>>      
> >>>>          the inner treat, but would fail for attributes with same
> >>>>          names.
> >>>> 
> >>>> Do you mean specifically the nesting of TREAT operators?  Again, I am
> >>>> surprised that this would not work.  Tests?  Jira?
> >>>> 
> >>>>        * Joins for supertypes and conditions on discriminators are not
> >>>>      
> >>>>      aware
> >>>>      
> >>>>          of the join type actually used in the treated join => left
> >>>>          join
> >>>>          should cascade up the type hierarchy and discriminator checks
> >>>>      
> >>>>      should
> >>>>      
> >>>>          contain OR DTYPE IS NULL for left join semantics. If treats
> >>>>      
> >>>>      are in
> >>>>      
> >>>>          subconditions the DTYPE checks might even be wrong
> >>>> 
> >>>> This "restriction" aspect is honestly Hibernate's biggest shortcoming
> >>>> in its TREAT support. Hibernate's "SQL generation machinery" simply
> >>>> was not built to support this.  At all.  I hacked together some
> >>>> support for TREAT on top of that legacy "SQL generation machinery",
> >>>> but it is very limited.
> >>>> 
> >>>> This aspect is specifically what we have discussed in terms of TREAT
> >>>> support improvements in SQM.  Keeping track of where the TREAT occurs
> >>>> so that we can later know how to properly handle it, whether that
> >>>> means we can skip parts of the inheritance join tree or maybe need to
> >>>> render some extra WHERE-clause restrictions...
> >>>> 
> >>>>        * Joins are generated for the whole hierarchy not only the
> >>>>      
> >>>>      types that
> >>>>      
> >>>>          are treated => this might seem to be "just" a performance
> >>>>      
> >>>>      problem,
> >>>>      
> >>>>          but IMO actually is a correctness problem as it makes a
> >>>>      
> >>>>      difference
> >>>>      
> >>>>          if you get e.g. 2 rows or 2 * TYPES rows especially for count
> >>>>      
> >>>>      queries.
> >>>> 
> >>>> Generating the joins for the whole hierarchy is important for HQL's
> >>>> implicit downcasting support. However, that said, there are attempts
> >>>> to restrict that already in place.  IIRC this only works for TREATs
> >>>> that occur in the FROM-clause specifically.  However, I thought that
> >>>> other TREAT operations were still handled in terms of adding
> >>>> restrictions when dictated.  So this might be specific to certain
> >>>> circumstances.
> >>>> 
> >>>> Again, which specific tests show this?  Jira?
> >>>> 
> >>>> ----
> >>>> 
> >>>> Some specifics of the plan...
> >>>> 
> >>>> First, internally within the query AST I want to make sure that we
> >>>> model *all* downcasts whether they are implicit or explicit.  In
> >>>> other words, in terms of AST both of these queries would result in
> >>>> 
> >>>> the same structure:
> >>>>   1. select e.someProp from MyEntity
> >>>>   2. select treat(e as MySub).someProp from MyEntity
> >>>> 
> >>>> Secondly, we need to keep track of various pieces of information
> >>>> pertaining to a downcast
> >>>> (see
> >>>> org.hibernate.sqm.query.from.Downcast/org.hibernate.sqm.query.from.Down
> >>>> c
> >>>> astable).>>
> >>>> 
> >>>> This includes info like:
> >>>>   1. The downcast "target"
> >>>>   2. The context in which the downcast occurred
> >>>>   3. Any/all contexts in which the downcast is used.
> >>>> 
> >>>> The last 2 items there would specifically lead to:
> >>>>    * Which specific inheritance joins are needed - and may indicate
> >>>>    
> >>>>      join type
> >>>>    
> >>>>    * Any extra restrictions we may need to add
> >> 
> >> _______________________________________________
> >> hibernate-dev mailing list
> >> hibernate-dev at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/hibernate-dev
> > 
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
> 
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev




More information about the hibernate-dev mailing list