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.bei...@gmail.com <mailto:christian.bei...@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@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/hibernate-dev _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev