EntityProxy & equals

373 views
Skip to first unread message

Hilco Wijbenga

unread,
Nov 14, 2011, 1:09:10 AM11/14/11
to GWT Users
Hi all,

I was trying to check the presence of an EntityProxy in a
Set<EntityProxy> [i.e. set.contains(proxy)]. This returned false even
though the proxy was an element of the set. As it turns out
EntityProxy.equals() doesn't work, or, more precisly, it seems to
behave as the default equals() and check reference equality instead of
value equality.

So how do I get a working value checking equals? Without it,
Set<EntityProxy> is just about useless. I didn't see anything relevant
in [1] and Google was no help either. (I did find a similar question
but it went unanswered.)

Cheers,
Hilco

[1] http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.html

Thomas Broyer

unread,
Nov 14, 2011, 3:45:16 AM11/14/11
to google-we...@googlegroups.com

Robert Quinn

unread,
Nov 14, 2011, 9:33:22 AM11/14/11
to Google Web Toolkit
Equality works as Thomas mentioned, so one basic question leaps to
mind: Why are you comparing EntityProxys from different contexts or
with different stableIds? Maybe there is a more centralized way you
could manage those EntityProxys so that you are not dispersing them in
various states/contexts across your app.

Hilco Wijbenga

unread,
Nov 14, 2011, 11:47:41 AM11/14/11
to google-we...@googlegroups.com
On 14 November 2011 06:33, Robert Quinn <quinn....@gmail.com> wrote:
> Equality works as Thomas mentioned, so one basic question leaps to
> mind: Why are you comparing EntityProxys from different contexts or
> with different stableIds?  Maybe there is a more centralized way you
> could manage those EntityProxys so that you are not dispersing them in
> various states/contexts across your app.

Firstly, I should have been more concerned about hashCode when working
with Sets but hashCode and equals go hand in hand and hashCode is part
of EntityProxyCategory as well.

The EntityProxy-s might be from different contexts but they are not
editable and all fields (including stableId) are the same. I checked
this. They all come from the database, through RF, so I have no
control over how many instances are created, AFAICT.

But I'm really confused now. I can see that equals/hashCode do what I
need them to do (i.e. compare stableId) but it's not working. Very
strange.

Hilco Wijbenga

unread,
Nov 14, 2011, 3:01:02 PM11/14/11
to google-we...@googlegroups.com

Okay, so Robert was spot on. The problem is with RequestContexts. The
set has a RequestContext (although I'm not sure why, AFAICT its
onSuccess method has already run) and the proxy does not (i.e.
BaseProxyCategory.requestContext(proxy) returns NULL).

I'm sure there is a good reason for the RequestContext check in
EntityProxyCategory.equals() but it seems more like a bug than a
feature to me. Because of this extra check sets and maps no longer
work as one would expect them to.

How do I remove an EntityProxy from its RequestContext? There doesn't
seem to be a close() method or similar on RequestContext. When is the
RequestContext set to NULL? How do I get sets/maps to work again?

Robert Quinn

unread,
Nov 14, 2011, 3:49:41 PM11/14/11
to Google Web Toolkit
I also have collections of EntityProxys, but I make the lifetime of
the collection the same as the lifetime of the RequestContext.

So after I do a CRUD operation, I refresh my collections in the new
RequestContext, and therefore don't have any inter-RequestContext
problems.


On Nov 14, 2:01 pm, Hilco Wijbenga <hilco.wijbe...@gmail.com> wrote:
> On 14 November 2011 08:47, Hilco Wijbenga <hilco.wijbe...@gmail.com> wrote:

Hilco Wijbenga

unread,
Nov 14, 2011, 7:25:15 PM11/14/11
to google-we...@googlegroups.com
On 14 November 2011 12:49, Robert Quinn <quinn....@gmail.com> wrote:
> I also have collections of EntityProxys, but I make the lifetime of
> the collection the same as the lifetime of the RequestContext.
>
> So after I do a CRUD operation, I refresh my collections in the new
> RequestContext, and therefore don't have any inter-RequestContext
> problems.

That just doesn't seem feasible, I'm afraid.

Basically what I do is the following:
1) request a list of proxies from the database (List<EntityProxy>, "list");
2) unrelated, at a later time in another place, new RequestContext for "entity";
3) add one proxy ("proxy") from "list" to a Set<EntityProxy> ("set");
(this "set" is part of "entity")
4) RequestContext.fire();
5) onSuccess();
6) unrelated, at a later time in another place, check that
entity.set.contains(proxy).

Is this really such a strange scenario?

Why would EntityProxyCategory.equals() include requestContext()? What
would be the impact of removing that particular check?

How do I get an EntityProxy to have a NULL RequestContext?

-sowdri-

unread,
Nov 14, 2011, 11:56:45 PM11/14/11
to google-we...@googlegroups.com
I use this class for copying proxies across contexts. May be helpful in your case too:

/**
 * Convenience method to copy an entity proxy to another request context.
 * 
 * @author sowdri
 * 
 */
public class RequestFactoryUtils {

public static <T extends BaseProxy> T copy(Class<T> clazz, T proxy,
RequestContext context) {

T newProxy = context.create(clazz);

if (proxy != null) {

AutoBean<T> oldBean = AutoBeanUtils.getAutoBean(proxy);
AutoBean<T> newBean = AutoBeanUtils.getAutoBean(newProxy);
AutoBeanCodex.decodeInto(AutoBeanCodex.encode(oldBean), newBean);

// newBean.setFrozen(true);
newProxy = newBean.as();
}

context.edit(newProxy);

return newProxy;
}
}

Robert Quinn

unread,
Nov 15, 2011, 4:10:18 PM11/15/11
to Google Web Toolkit
Two approaches that jump to my mind are:
1. Try to make the contexts match whenever you compare them, e.g. by
using sowdri's method.
2. For you context-less collection of objects, get away from
EntityProxy equality semantics by wrapping/translating the objects in
a class that has the equality semantics that you define.

On Nov 14, 6:25 pm, Hilco Wijbenga <hilco.wijbe...@gmail.com> wrote:

-sowdri-

unread,
Nov 15, 2011, 11:54:36 PM11/15/11
to google-we...@googlegroups.com
>>  For you context-less collection of objects, get away from 
EntityProxy equality semantics by wrapping/translating the objects in 
a class that has the equality semantics that you define. 

Building upon Robert's solution:

The process of adding and removing proxies to collections could be 'delegated' to a new class, which takes the 'collection' and a respective 'comparator implementation', for ex:

public class CollectionManager<T extends EntityProxy> {
  void add(Collection<T> collection, T proxy, Comparator<T> comparator) { // ... };
  void remove(Collection<T> collection, T proxy, Comparator<T> comparator) { // ... };
}

I guess, in this case even proxies belonging to multiple contexts could be maintained in the collection. 
Reply all
Reply to author
Forward
0 new messages