Generics 带有泛型的类型化类的RequestFactory客户端继承

Generics 带有泛型的类型化类的RequestFactory客户端继承,generics,inheritance,gwt,polymorphism,requestfactory,Generics,Inheritance,Gwt,Polymorphism,Requestfactory,我想知道,是否可以将请求工厂代理/上下文的通用类用于所有实体的通用操作,如getById(Long id) 在我的应用程序中,我将有许多字典,比如类,它们只有id和name参数,因此我想编写一次功能,并通过rest类中的继承使用它: 下面是服务器实现: 域模型类 @MappedSuperclass public class GenericModel<T extends GenericModel<T>> implements Identifiable, Versionab

我想知道,是否可以将请求工厂代理/上下文的通用类用于所有实体的通用操作,如
getById(Long id)

在我的应用程序中,我将有许多字典,比如类,它们只有
id
name
参数,因此我想编写一次功能,并通过rest类中的继承使用它:

下面是服务器实现:

域模型类

@MappedSuperclass
public  class GenericModel<T extends GenericModel<T>> implements Identifiable, Versionable {
    @Transient
    protected Class<T> entityClass;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Version
    private Integer version;

    // setter & getter
    @Override
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    @Override
    public Integer getVersion() {return version;}
    public void setVersion(Integer version) {this.version = version;}

    // constructor
    public GenericModel() {
        Class<?> obtainedClass = getClass();
        Type genericSuperclass = null;
        for (;;) {
            genericSuperclass = obtainedClass.getGenericSuperclass();
            if (genericSuperclass instanceof ParameterizedType) {
                break;
            }
            obtainedClass = obtainedClass.getSuperclass();
        }
        ParameterizedType genericSuperclass_ = (ParameterizedType) genericSuperclass;
        try {
            entityClass = ((Class) ((Class) genericSuperclass_
                    .getActualTypeArguments()[0]));
        } catch (ClassCastException e) {
            entityClass = guessEntityClassFromTypeParametersClassTypedArgument();
        }
    }


    public GenericModel(Long id) {
        this();
        this.id = id;
    }
}


以下是客户端执行实现:

    List<GenericDictionaryProxy> proxies = new LinkedList<GenericDictionaryProxy>();
    GenericDictionaryContext context = createRequestFactory().getGenericDictionaryContext();

    context.get().to(new Receiver<List<GenericDictionaryProxy>>() {
        @Override
        public void onSuccess(List<GenericDictionaryProxy> response) {
            for(GenericDictionaryProxy p: response) {
                cont.add(new Label(p.getId() + " " + p.getName() + ", " + p.getVersion() ));
            }
        }
    }).fire();
List proxies=newlinkedlist();
GenericDictionaryContext上下文=createRequestFactory().getGenericDictionaryContext();
context.get(){
@凌驾
成功时公共无效(列表响应){
for(GenericDictionaryProxy p:response){
cont.add(新标签(p.getId()+“”+p.getName()+”,“+p.getVersion());
}
}
}).fire();
它将返回一个对象列表,其中包含参数:id、版本、名称

不幸的是,它不起作用

我的IDE向我显示错误:

Could not find domain method similar to java.util.List<pl.derp.server.model.GenericDictionaryModel<T>> getListOrderedByName()   GenericDictionaryContext.java   /Index/src/main/java/pl/derp/shared/rf  line 26 Annotation Problem (Java 6 processor)
The method to(Receiver<? super List<GenericProxy>>) in the type Request<List<GenericProxy>> is not applicable for the arguments (new Receiver<List<GenericDictionaryProxy>>(){})    GoodbyeViewImpl.java    /Index/src/main/java/pl/derp/client/view    line 91 Java Problem
找不到类似java.util.List getListOrderedByName()GenericDictionaryContext.java/Index/src/main/java/pl/derp/shared/rf line 26注释问题的域方法(java 6处理器)

(ReceiverYes)的方法对您有效,但是您需要在RequestContext上为所有需要的不同类型添加@ExtraTypes注释

不久前我发布了一个完整的示例

编辑

要使其工作,您应该让您的泛型requestcontext使用泛型。这是我过去所做的,对我来说是正确的。您不需要泛型上的额外类型来工作,因为您将告诉它类型

@Service(value = GenericDao.class, locator = MyServiceLocator.class)
public interface GenericContext<T extends GenericProxy> extends RequestContext {
    Request<T> getBy(Long id);
    Request<List<T>> get();
    Request<Void> save(T entity);
}


@Service(value = GenericDictionaryDao.class, locator = MyServiceLocator.class)
@ExtraTypes( {
    GenericDictionaryProxy.class,
    PageIProxy.class,
    ContentIProxy.class
    } )
public interface GenericDictionaryContext extends GenericContext<GenericDictionaryProxy> {
    public Request<List<GenericDictionaryProxy>> getListOrderedByName();

    // These used to be required due to a bug a while ago. Test without it
    // but if you get a method about an unknown method then this is the issue.
    Request<GenericDictionaryProxy> getBy(Long id);
    Request<List<GenericDictionaryProxy>> get();
    Request<Void> save(T entity);
}
@Service(value=GenericDao.class,locator=MyServiceLocator.class)
公共接口GenericContext扩展了RequestContext{
请求getBy(长id);
请求get();
请求保存(T实体);
}
@服务(value=GenericDictionaryDao.class,locator=MyServiceLocator.class)
@外部类型({
GenericDictionaryProxy.class,
PageIProxy.class,
ContentIProxy.class
} )
公共接口GenericDictionaryContext扩展了GenericContext{
公共请求getListOrderedByName();
//由于前一段时间的一个bug,这些都是必需的。在没有它的情况下进行测试
//但是如果你得到一个关于未知方法的方法,那么这就是问题所在。
请求getBy(长id);
请求get();
请求保存(T实体);
}
我不久前发现了一个问题,不确定是否已修复,但我还必须将方法添加到扩展类中。我不介意,因为我仍然可以在需要时使用GenericContext,并且一切正常。这使我能够使用guava LoadingCache创建一个很好的实体缓存机制

快速示例。

public class EntityCache<T extends GenericProxy, R extends GenericContext<T>>  {

    private R requestContext;

    public EntityCache(R requestContext) {
        this.requestContext = requestContext;
    }

    public T get(Long key) {
       // get from loading cache but this is a simple example.
       requestContext.get(key);
    }

}
公共类实体缓存{
私有请求者上下文;
公共EntityCache(请求者上下文){
this.requestContext=requestContext;
}
公用T get(长键){
//从加载缓存中获取,但这是一个简单的示例。
requestContext.get(key);
}
}

嘿。我已经像你告诉我的那样添加了
@ExtraTypes
注释,但不幸的是它没有帮助。请再次查看我的帖子,我已经更新了它。缓存类非常有趣。你可以发布客户端的代码吗?你如何创建工厂并调用泛型方法?你可以发布上下文类的代码吗?我可以让它编译。
@ProxyFor(value = GenericModel.class, locator = GenericLocator.class)
public interface GenericProxy extends EntityProxy {
    public Long getId();
    public void setId(Long id);
    public Integer getVersion();
    public void setVersion(Integer version);
}
@ProxyFor(value = GenericDictionaryModel.class, locator = GenericLocator.class)
public interface GenericDictionaryProxy extends GenericProxy {
    public String getName();
    public void setName(String name);
}
@ProxyFor(value = PageI.class, locator = GenericLocator.class)
public interface PageIProxy extends GenericDictionaryProxy {
    public List<ContentIProxy> getContents();
    public void setContents(List<ContentIProxy> contents);
    public static final String Contents = "contents";
}
@Service(value = GenericDao.class, locator = MyServiceLocator.class)
@ExtraTypes( {
    GenericProxy.class 
    } )
public interface GenericContext extends RequestContext {
    Request<GenericProxy> getBy(Long id);
    Request<List<GenericProxy>> get();
    Request<Void> save(GenericProxy entity);
}
@Service(value = GenericDictionaryDao.class, locator = MyServiceLocator.class)
@ExtraTypes( {
    GenericDictionaryProxy.class,
    PageIProxy.class,
    ContentIProxy.class
    } )
public interface GenericDictionaryContext extends GenericContext {
    public Request<List<GenericDictionaryProxy>> getListOrderedByName();
}
public interface Services extends RequestFactory {
    GenericContext getGenericContext();
    GenericDictionaryContext getGenericDictionaryContext();

}
    List<GenericDictionaryProxy> proxies = new LinkedList<GenericDictionaryProxy>();
    GenericDictionaryContext context = createRequestFactory().getGenericDictionaryContext();

    context.get().to(new Receiver<List<GenericDictionaryProxy>>() {
        @Override
        public void onSuccess(List<GenericDictionaryProxy> response) {
            for(GenericDictionaryProxy p: response) {
                cont.add(new Label(p.getId() + " " + p.getName() + ", " + p.getVersion() ));
            }
        }
    }).fire();
Could not find domain method similar to java.util.List<pl.derp.server.model.GenericDictionaryModel<T>> getListOrderedByName()   GenericDictionaryContext.java   /Index/src/main/java/pl/derp/shared/rf  line 26 Annotation Problem (Java 6 processor)
The method to(Receiver<? super List<GenericProxy>>) in the type Request<List<GenericProxy>> is not applicable for the arguments (new Receiver<List<GenericDictionaryProxy>>(){})    GoodbyeViewImpl.java    /Index/src/main/java/pl/derp/client/view    line 91 Java Problem
[INFO]    Tracing compile failure path for type 'pl.derp.client.view.GoodbyeViewImpl'
[INFO]       [ERROR] Errors in 'file:/home/korbeldaniel/git/derp3/tutorial/src/main/java/pl/derp/client/view/GoodbyeViewImpl.java'
[INFO]          [ERROR] Line 91: The method to(Receiver<? super List<GenericProxy>>) in the type Request<List<GenericProxy>> is not applicable for the arguments (new Receiver<List<GenericDictionaryProxy>>(){})
[INFO]    [ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
@Service(value = GenericDao.class, locator = MyServiceLocator.class)
public interface GenericContext<T extends GenericProxy> extends RequestContext {
    Request<T> getBy(Long id);
    Request<List<T>> get();
    Request<Void> save(T entity);
}


@Service(value = GenericDictionaryDao.class, locator = MyServiceLocator.class)
@ExtraTypes( {
    GenericDictionaryProxy.class,
    PageIProxy.class,
    ContentIProxy.class
    } )
public interface GenericDictionaryContext extends GenericContext<GenericDictionaryProxy> {
    public Request<List<GenericDictionaryProxy>> getListOrderedByName();

    // These used to be required due to a bug a while ago. Test without it
    // but if you get a method about an unknown method then this is the issue.
    Request<GenericDictionaryProxy> getBy(Long id);
    Request<List<GenericDictionaryProxy>> get();
    Request<Void> save(T entity);
}
public class EntityCache<T extends GenericProxy, R extends GenericContext<T>>  {

    private R requestContext;

    public EntityCache(R requestContext) {
        this.requestContext = requestContext;
    }

    public T get(Long key) {
       // get from loading cache but this is a simple example.
       requestContext.get(key);
    }

}