Can an interface serve as proxy for more than one class in RequestFactory?

93 views
Skip to first unread message

Ryan McFall

unread,
Jun 27, 2011, 6:40:05 AM6/27/11
to Google Web Toolkit
I have two domain objects that implement the same interface on the
server, and a third class that contains a (heterogeneous) List of
those objects. I need to be able to expose this list on the client
side. The domain objects do not share a common super-class (they
instead delegate the common functionality to another object).

Given that all proxy interfaces are required to extend BaseProxy, I
cannot figure out how to write multiple proxies that will have a
parent interface in common. I tried making a base interface that both
proxies extend, but that base interface must extend EntityProxy, and
the GWT compiler complains if you have an interface that extends
EntityProxy but does not have a ProxyFor annotation.

I am wondering (although I suspect the answer is no) whether I can
have a single interface declare that it is a proxy for multiple
entities. If not, other ideas for making this work are welcome.

Thanks in advance for any ideas.
Ryan

Thomas Broyer

unread,
Jun 27, 2011, 10:00:59 AM6/27/11
to google-we...@googlegroups.com


On Monday, June 27, 2011 12:40:05 PM UTC+2, Ryan McFall wrote:
I have two domain objects that implement the same interface on the
server, and a third class that contains a (heterogeneous) List of
those objects.  I need to be able to expose this list on the client
side.  The domain objects do not share a common super-class (they
instead delegate the common functionality to another object).

Given that all proxy interfaces are required to extend BaseProxy, I
cannot figure out how to write multiple proxies that will have a
parent interface in common.  I tried making a base interface that both
proxies extend, but that base interface must extend EntityProxy, and
the GWT compiler complains if you have an interface that extends
EntityProxy but does not have a ProxyFor annotation.

The interface need not extend EntityProxy, you can have:
interface BaseInterface { ... }
interface FooProxy extends BaseInterface, EntityProxy { }
interface BarProxy extends BaseInterface, EntityProxy { }

...but then you obviously cannot have a proxy declare a list that contain both FooProxy and BarProxy, as a Collection<BaseInterface> would be rejected because BaseInterface doesn't extend EntityProxy or ValueProxy.

BUT!
  • The hierarchy of proxy interfaces need not mimic the one of domain objects on the server-side. You could have "interface BarProxy extends FooProxy" for example.
  • or, because you can have more than one proxy interface for the same domain object, you could annotate the base interface with a @ProxyFor for one of the domain class.

I am wondering (although I suspect the answer is no) whether I can
have a single interface declare that it is a proxy for multiple
entities.  If not, other ideas for making this work are welcome.

You're right: an interface can only map to a single domain class. Moreover, you cannot use an interface in a @ProxyFor, as the RequestFactoryInterfaceValidator used by the RequestFactoryServlet will ultimately flag it as an error (so you unfortunately cannot use the interface implemented by both your domain objects).

RequestFactory does not (yet) support polymorphism, so your collection can only ever contain a single "interface".

Not sure there's a solution to your problem besides refactoring your domain classes (but maybe if you share a bit more information, maybe there's a solution)

Ryan McFall

unread,
Jun 27, 2011, 11:48:08 AM6/27/11
to Google Web Toolkit
Thanks for the reply. I think you're right that there's no great
solution to my problem.

I've got it solved at the moment by creating a client side interface,
and wrapper classes for the two proxies that both implement that
client-side interface (basically mimicking the functionality of the
common server interface). I don't like it, but it seems to be
working.

Ryan

On Jun 27, 10:00 am, Thomas Broyer <t.bro...@gmail.com> wrote:
> On Monday, June 27, 2011 12:40:05 PM UTC+2, Ryan McFall wrote:
>
> > I have two domain objects that implement the same interface on the
> > server, and a third class that contains a (heterogeneous) List of
> > those objects.  I need to be able to expose this list on the client
> > side.  The domain objects do not share a common super-class (they
> > instead delegate the common functionality to another object).
>
> > Given that all proxy interfaces are required to extend BaseProxy, I
> > cannot figure out how to write multiple proxies that will have a
> > parent interface in common.  I tried making a base interface that both
> > proxies extend, but that base interface must extend EntityProxy, and
> > the GWT compiler complains if you have an interface that extends
> > EntityProxy but does not have a ProxyFor annotation.
>
> The interface need not extend EntityProxy, you can have:
> interface BaseInterface { ... }
> interface FooProxy extends BaseInterface, EntityProxy { }
> interface BarProxy extends BaseInterface, EntityProxy { }
>
> ...but then you obviously cannot have a proxy declare a list that contain
> both FooProxy and BarProxy, as a Collection<BaseInterface> would be rejected
> because BaseInterface doesn't extend EntityProxy or ValueProxy.
>
> BUT!
>
>    - The hierarchy of proxy interfaces need not mimic the one of domain
>    objects on the server-side. You could have "interface BarProxy extends
>    FooProxy" for example.
>    - or, because you can have more than one proxy interface for the same
>    domain object, you could annotate the base interface with a @ProxyFor for
>    one of the domain class.
>
> I am wondering (although I suspect the answer is no) whether I can
>
> > have a single interface declare that it is a proxy for multiple
> > entities.  If not, other ideas for making this work are welcome.
>
> You're right: an interface can only map to a single domain class. Moreover,
> you cannot use an interface in a @ProxyFor, as the
> RequestFactoryInterfaceValidator used by the RequestFactoryServlet will
> ultimately flag it as an error (so you unfortunately cannot use the
> interface implemented by both your domain objects).
>
> RequestFactory does not (yet<http://code.google.com/p/google-web-toolkit/issues/detail?id=5367>)

Aldo Neto

unread,
Jun 21, 2015, 3:29:01 PM6/21/15
to google-web-toolkit
HI,

I know this is an old thread, but I'm having a similar problem.

I have a class A that is an entity on my server side and a class B that extends A (with PrimaryKeyJoinColumn). So, in other words I have:

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class A {
...
}

@Entity
@PrimaryKeyJoinColumn(name="a_id", referencedColumnName="id")
public class B extends A {
...
}

I already have A extending EntityProxy:

@ProxyFor(A.class)
public interface AProxy extends EntityProxy {
...
}

And now I need to map B as an Entity Proxy as well, but I'm getting an exception. What I did is:

@ProxyFor(B.class)
public interface BProxy extends AProxy, EntityProxy {
...
}

but I get the following exception:
BProxy is not an EntityProxy type
    at com.google.web.bindery.requestfactory.shared.impl.IdFactory.asEntityProxy(IdFactory.java:66)


Is it possible to do what I'm trying here? If so, how?

Thanks,
Aldo


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.


Thomas Broyer

unread,
Jun 21, 2015, 5:31:54 PM6/21/15
to google-we...@googlegroups.com, tum...@gmail.com


On Sunday, June 21, 2015 at 9:29:01 PM UTC+2, Aldo wrote:
HI,

I know this is an old thread, but I'm having a similar problem.

I have a class A that is an entity on my server side and a class B that extends A (with PrimaryKeyJoinColumn). So, in other words I have:

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class A {
...
}

@Entity
@PrimaryKeyJoinColumn(name="a_id", referencedColumnName="id")
public class B extends A {
...
}

I already have A extending EntityProxy:

@ProxyFor(A.class)
public interface AProxy extends EntityProxy {
...
}

And now I need to map B as an Entity Proxy as well, but I'm getting an exception. What I did is:

@ProxyFor(B.class)
public interface BProxy extends AProxy, EntityProxy {
...
}

but I get the following exception:
BProxy is not an EntityProxy type
    at com.google.web.bindery.requestfactory.shared.impl.IdFactory.asEntityProxy(IdFactory.java:66)


Is it possible to do what I'm trying here? If so, how?

Assuming you get that error on the client side, it actually means that your RequestFactory doesn't know about BProxy.
BProxy has to be referenced from a RequestContext or another EntityProxy/ValueProxy transitively referenced from your RequestFactory interface.
You might have to annotate one of your RequestContext or proxy with @ExtraTypes(BProxy.class).

Aldo Neto

unread,
Jun 21, 2015, 6:35:37 PM6/21/15
to google-web-toolkit
Thank you for your reply. It solved the issue.

Now I'm struggling with the editor part. I don't know how to implement the editor so it can work with both classes A and B (where B extends A). I'd like to use a TabPanel and display A in one tab and B in the other one, but I'm having trouble with shared fields. In other words, once B has the same fields as A (plus some others), how can I have two boxes with same name in both tabs? Is there a way to use editor in this scenario?

Once again, thanks for your quick response.

Aldo


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-tool...@googlegroups.com.

To post to this group, send email to google-we...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages