Is this guaranteed behavior of JPAQuery, JPASubQuery, JPAUpdateClause, and JPADeleteClause?

84 views
Skip to first unread message

Michael Tontchev

unread,
Apr 22, 2015, 2:22:25 PM4/22/15
to quer...@googlegroups.com
I notice that all of the above classes, when they have methods called from them to build a query, modify the current object and then return it. Is it guaranteed that this will remain so? That is, that the methods will always modify the current object instead of creating a new query to modify.

For example, say you do

JPAQuery q = new JPAQuery(em);

q.from(user).where(user.name.eq("Ted"));

that from() call modifies q. Same with the where() call. But they also return a JPAQuery object. Are we guaranteed that they will always return the current object? Or is it possible that in the future you might decide to make each call return a new object, leaving the original q unchaged?

(Of course, disregard this question as it regards the clone() methods).

I'm trying to extend the classes mentioned above, but if new objects are returned, I'd need to call clone(JPAQuery), which is protected and I can't access. (And the update clause and delete clause don't have clone()).

Thanks!

Timo Westkämper

unread,
Apr 22, 2015, 2:25:10 PM4/22/15
to Querydsl on behalf of Michael Tontchev
Hi.

This behaviour won't change with the 4.0.0 release, and will be present in all 4.* releases for backwards compatibility.

Timo

--
You received this message because you are subscribed to the Google Groups "Querydsl" group.
To unsubscribe from this group and stop receiving emails from it, send an email to querydsl+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Tontchev

unread,
Apr 22, 2015, 2:40:14 PM4/22/15
to quer...@googlegroups.com
Thanks! Also, is there any reason JPAQuery's clone(JPAQuery) method is protected? I'm trying to override clone(), but that requires me calling super.clone(). When I call it, I get back an object of type JPAQuery. I need to then return a CustomJPAQuery object. If I could access clone(JPAQuery) I could just do this.clone(super.clone()), but I can't access it.


On Wednesday, April 22, 2015 at 2:25:10 PM UTC-4, timowest wrote:
Hi.

This behaviour won't change with the 4.0.0 release, and will be present in all 4.* releases for backwards compatibility.

Timo

Ruben Dijkstra

unread,
Apr 22, 2015, 2:42:59 PM4/22/15
to quer...@googlegroups.com, Michael Tontchev via Querydsl
Hi,

It is an implementation detail that callers don't have to worry about (it's somewhat like a copy constructor, but not a contructor).
Protected members are visible by subclasses, so what exactly doesn't work?

Best regards,

Ruben

On Wed, 22 Apr 2015 20:40:14 +0200, Michael Tontchev via Querydsl <querydsl+APn2wQeUt6jEuBVj9FETOEr...@googlegroups.com> wrote:

Thanks! Also, is there any reason JPAQuery's clone(JPAQuery) method is protected? I'm trying to override clone(), but that requires me calling super.clone(). When I call it, I get back an object of type JPAQuery. I need to then return a CustomJPAQuery object. If I could access clone(JPAQuery) I could just do this.clone(super.clone()), but I can't access it.

On Wednesday, April 22, 2015 at 2:25:10 PM UTC-4, timowest wrote:
Hi.

This behaviour won't change with the 4.0.0 release, and will be present in all 4.* releases for backwards compatibility.

Timo

On Wed, Apr 22, 2015 at 9:22 PM, Michael Tontchev via Querydsl <querydsl+APn2wQeUt6jEuBVj9FETOEr...@googlegroups.com> wrote:
I notice that all of the above classes, when they have methods called from them to build a query, modify the current object and then return it. Is it guaranteed that this will remain so? That is, that the methods will always modify the current object instead of creating a new query to modify.

For example, say you do

JPAQuery q = new JPAQuery(em);

q.from(user).where(user.name.eq("Ted"));

that from() call modifies q. Same with the where() call. But they also return a JPAQuery object. Are we guaranteed that they will always return the current object? Or is it possible that in the future you might decide to make each call return a new object, leaving the original q unchaged?

(Of course, disregard this question as it regards the clone() methods).

I'm trying to extend the classes mentioned above, but if new objects are returned, I'd need to call clone(JPAQuery), which is protected and I can't access. (And the update clause and delete clause don't have clone()).

Thanks!
--
You received this message because you are subscribed to the Google Groups "Querydsl" group.
To unsubscribe from this group and stop receiving emails from it, send an email to querydsl+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Tontchev

unread,
Apr 22, 2015, 2:57:59 PM4/22/15
to quer...@googlegroups.com
Sigh, I guess I'm just an idiot, haha. A month ago when I had initially extended JPAQuery I wanted to override the private methods as well, but apparently I got so into it I overrode the protected methods in the same way (using reflection), forgetting that protected methods can be overridden in subclasses.

Thanks :)


On Wednesday, April 22, 2015 at 2:42:59 PM UTC-4, Ruben Dijkstra wrote:
Hi,

It is an implementation detail that callers don't have to worry about (it's somewhat like a copy constructor, but not a contructor).
Protected members are visible by subclasses, so what exactly doesn't work?

Best regards,

Ruben

On Wed, 22 Apr 2015 20:40:14 +0200, Michael Tontchev via Querydsl <querydsl+APn2wQeUt6jEuBVj9FETOEr34G61O6V5VHz2H2bqynp57dsdUszLXiT@googlegroups.com> wrote:

Thanks! Also, is there any reason JPAQuery's clone(JPAQuery) method is protected? I'm trying to override clone(), but that requires me calling super.clone(). When I call it, I get back an object of type JPAQuery. I need to then return a CustomJPAQuery object. If I could access clone(JPAQuery) I could just do this.clone(super.clone()), but I can't access it.

On Wednesday, April 22, 2015 at 2:25:10 PM UTC-4, timowest wrote:
Hi.

This behaviour won't change with the 4.0.0 release, and will be present in all 4.* releases for backwards compatibility.

Timo

On Wed, Apr 22, 2015 at 9:22 PM, Michael Tontchev via Querydsl <querydsl+APn2wQeUt6jEuBVj9FETOEr34G61O6V5VHz2H2bqynp57dsdUszLXiT@googlegroups.com> wrote:
I notice that all of the above classes, when they have methods called from them to build a query, modify the current object and then return it. Is it guaranteed that this will remain so? That is, that the methods will always modify the current object instead of creating a new query to modify.

For example, say you do

JPAQuery q = new JPAQuery(em);

q.from(user).where(user.name.eq("Ted"));

that from() call modifies q. Same with the where() call. But they also return a JPAQuery object. Are we guaranteed that they will always return the current object? Or is it possible that in the future you might decide to make each call return a new object, leaving the original q unchaged?

(Of course, disregard this question as it regards the clone() methods).

I'm trying to extend the classes mentioned above, but if new objects are returned, I'd need to call clone(JPAQuery), which is protected and I can't access. (And the update clause and delete clause don't have clone()).

Thanks!
--
You received this message because you are subscribed to the Google Groups "Querydsl" group.
To unsubscribe from this group and stop receiving emails from it, send an email to querydsl+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Tontchev

unread,
Apr 22, 2015, 3:16:34 PM4/22/15
to quer...@googlegroups.com
Alright - but, while I'm at it: are the clone() methods shallow or deep?

Michael Tontchev

unread,
Apr 22, 2015, 3:19:43 PM4/22/15
to quer...@googlegroups.com
Seems to me that it, shallow, right? So yeah, I guess like a copy constructor.

Michael Tontchev

unread,
Apr 22, 2015, 3:21:34 PM4/22/15
to quer...@googlegroups.com
(Sorry, the copy constructor part I mentioned is irrelevant)

timowest

unread,
Apr 22, 2015, 4:19:53 PM4/22/15
to quer...@googlegroups.com
The clone methods provide a deep copy of the contents, at least the QueryMetadata instance.

Michael Tontchev

unread,
Apr 22, 2015, 4:54:49 PM4/22/15
to quer...@googlegroups.com
Ah, yes. I was looking at the clone method inherited from AbstractJPAQuery, which has this:

hints.putAll(query.hints); //line 346 of AbstractJPAQuery

And the putAll method of HashMultimap doesn't make deep copies.

But I see you meant the clones specifically defined in JPAQuery.

Thanks!

Michael Tontchev

unread,
Apr 28, 2015, 7:47:02 PM4/28/15
to quer...@googlegroups.com
I just spent about 4 hours trying to find a bug in my code, when I realized that AbstractJPAQuery's clone(JPAQuery) method doesn't in fact fully clone the parameter. Instead, this method is called by other clone methods in addition to them to copy that JPAQuery's contents. Is it possible to note this somewhere in the documentation? It would save future developers a lot of headaches.
Reply all
Reply to author
Forward
0 new messages