[hibernate-dev] Treat support

Emond Papegaaij emond.papegaaij at topicus.nl
Tue Aug 23 05:36:20 EDT 2016


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=5ddc74f60
> 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.Downc
> >> 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




More information about the hibernate-dev mailing list