The original API was never designed with these use-case in mind. So
you are stuck, unfortunately, between the rock (backwards
compatibility) and hard place (changing the API to accurately reflect
the situation).
Personally, I tend toward correcting bad API designs. One argument is
that the design of the APIs here is a bug, if that helps justify it.
Guess it all comes down to how strongly you feel about the API modeling
an inaccurate view.
On Fri 29 Jun 2012 02:31:50 PM CDT, Linda DeMichiel wrote:
> Hi Steve, all,
>
> My concern here is that this is a backwards incompatible change with
> regard to Subquery#getParent().
>
> I'm not sure what the best thing to do here is. I've attached revisions
> of CriteriaUpdate and CriteriaDelete that try to work around the problem,
> but I'm really not happy about how these abuse the typing.
>
> Suggestions appreciated.
>
> thanks,
>
> -Linda
>
>
> On 6/25/2012 12:51 PM, Steve Ebersole wrote:
>> Something like:
>>
>> public interface Criteria<T> {
>> <U> Subquery<U> subquery(Class<U> type);
>>
>> Criteria<T> where(Expression<Boolean> restriction);
>>
>> Criteria<T> where(Predicate... restrictions);
>>
>> Predicate getRestriction();
>> }
>>
>> public interface SelectionCriteria extends Criteria {
>> // rest of stuff currently on AbstractQuery,
>> // or just redefine AbstractQuery to extend Criteria
>> }
>>
>> public interface Subquery extends SelectionCriteria {
>> // not completely backwards compatible, but most correct imo:
>> public Criteria getParent();
>>
>> // rest same
>> }
>>
>> public interface CriteriaQuery extends SelectionCriteria {
>> ...
>> }
>>
>> public interface CriteriaUpdate extends Criteria {
>> ...
>> }
>>
>> public interface CriteriaDelete extends Criteria {
>> ...
>> }
>>
>>
>> On Mon 25 Jun 2012 02:41:55 PM CDT, Steve Ebersole wrote:
>>> Sorry, that second sentence should have asked whether
>>> Subquery#getParent could just return the new "base contract"
>>> referenced in the last sentence....
>>>
>>> On Mon 25 Jun 2012 02:34:09 PM CDT, Steve Ebersole wrote:
>>>> I also think Subquery#getParent should work if the parent is a
>>>> CriteriaUpdate/CriteriaDelete. Couldn't Subquery#getParent just
>>>> return Query?
>>>>
>>>> Sure, but AbstractQuery also defines `public Set<Root<?>> getRoots()`
>>>> which is a total misnomer in the case of
>>>> CriteriaUpdate/CriteriaDelete.
>>>>
>>>> I think a new base contract would be better, though not totally
>>>> backwards compatible.
>>>>
>>>> On Mon 25 Jun 2012 02:09:13 PM CDT, Linda DeMichiel wrote:
>>>>> Hi Steve, all,
>>>>>
>>>>> Steve, thanks for pointing this problem out -- good catch.
>>>>>
>>>>> On 6/24/2012 8:31 AM, Steve Ebersole wrote:
>>>>>> In implementing theses, I ran into 2 questions:
>>>>>>
>>>>>> 1) In terms of a Subquery associated with a
>>>>>> CriteriaUpdate/CriteriaDelete, what should be the return for the
>>>>>> Subquery#getParent which is defined to return an AbstractQuery which
>>>>>> neither CriteriaUpdate/CriteriaDelete implement.
>>>>>>
>>>>>
>>>>> If Subquery#getParent is going to work (which I think it needs to),
>>>>> then I think we are
>>>>> back to CriteriaUpdate/CriteriaDelete having to extend AbstractQuery.
>>>>>
>>>>>> 2) Seems to me we duplicate the effort to define the Root here; 2
>>>>>> calls when one would suffice. First users pass the
>>>>>> entity class to be updated/deleted to the CriteriaBuilder method,
>>>>>> then they have to call one of the from() methods on
>>>>>> CriteriaUpdate/CriteriaDelete. But unless I miss something the
>>>>>> actual
>>>>>> "entity type" of the from argument has to be the
>>>>>> same as the one passed to CriteriaBuilder. Long story short,
>>>>>> seems to
>>>>>> me that we could simply do away with the from()
>>>>>> methods and remove the need for the user to call the second method.
>>>>>
>>>>> If CriteriaUpdate/CriteriaDelete need to extend AbstractQuery, then I
>>>>> think this becomes a moot point,
>>>>> as from() is defined there.
>>>>>
>>>>> -Linda
>>>>>