具有泛型的类型化类的 RequestFactory 客户端继承 [英] RequestFactory client-side inheritance of typed class with generics

查看:25
本文介绍了具有泛型的类型化类的 RequestFactory 客户端继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to know, is it possible to use generic classes of request factory proxy/context for common actions for all entities, like getById(Long id).

在我的应用程序中,我将有许多像类这样的字典,它们只有 idname 参数,所以我想编写一次功能并通过继承使用它在休息课上:

In my app I will have many dictionaries like classes, that will have only id and name parameters, so I would like to write once functionality and use it through inheritance in rest classes:

这是服务器实现:

领域模型类

@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;
    }
}

<小时>

   @MappedSuperclass
    public abstract class GenericDictionaryModel<T extends GenericModel<T>> extends GenericModel<T> {

        private String name;
        @Transient
        private String optionDisplayName;
    //  private boolean active = true;

        public String getName() {return name;}
        public void setName(String name) {this.name = name;}
    //  public boolean getActive() {return active;}
    //  public void setActive(boolean stat) {this.active = stat;}
        public String getOptionDisplayName() {return optionDisplayName;}
        public void setOptionDisplayName(String optionDisplayName) {this.optionDisplayName = optionDisplayName;}

        public GenericDictionaryModel() {
            super();
        }
        public GenericDictionaryModel(Long id, String name) {
            super(id);
            this.name = name;
        }

    }

<小时>

@Entity
public class PageI extends GenericDictionaryModel<PageI> {

    @ManyToMany(cascade = CascadeType.ALL)
    private List<Content> contents;


    /* Getters and Setters */
    public List<Content> getContents() {
        return contents;
    }

    public void setContents(List<Content> contents) {
        this.contents = contents;
    }



}

<小时>

DAO 类


DAO classes

public class GenericDao<T extends GenericModel<T>> {
    private Logger logger = LoggerFactory.getLogger(this.getClass().getCanonicalName());
    @Transient protected Class<T> entityClass;


    public GenericDao() {
        super();
    }
    public GenericDao(Class<? extends GenericModel<T>> clazz) {
        this.entityClass = (Class<T>) clazz;
    }

    public T getBy(Long id) {
        return JPA.em().find(entityClass, id);
    }
    public List<GenericModel<T>> get() {
        logger.error("trying to get data from db");
        return getList();
    }
//  public List<T> get() {
//  }
    public List<GenericModel<T>> getList() {
        List<T> resultList = JPA.em().createQuery("FROM " + entityClass.getSimpleName()).getResultList();

        logger.error(resultList.toString());
        return JPA.em().createQuery("FROM " + entityClass.getSimpleName()).getResultList();
    }
}

<小时>

public class GenericDictionaryDao<T extends GenericDictionaryModel<T>> extends GenericDao<T>{
    private Logger logger = LoggerFactory.getLogger(this.getClass().getCanonicalName());

//  public T getBy(Long id) {
//      return super.getBy(id);
//    }
    public List<GenericModel<T>> getByName() {
        return super.get();
    }



//  public List<T> getListOrderedByName() {
//  public List<GenericDictionaryModel> getListOrderedByName() {
    public List<GenericDictionaryModel> getListOrderedByName2() {
        return null;
    }
    public List<GenericDictionaryModel<T>> getListOrderedByName() {
        try {
            return JPA.em()
                      .createQuery("FROM " + entityClass.getSimpleName() + " ORDER BY name")
                      .getResultList();
        } catch (ClassCastException e) {
            return new LinkedList<GenericDictionaryModel<T>>();
        }
//      return null;
    }
}

这里是共享实现:

代理:

@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();

}

这里是客户端执行实现:

Here is client execution implementation:

    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();

它应该返回一个带有参数的对象列表:id、版本、名称.

Which should return me a List of object with parameters: id, version, name.

不幸的是,它不起作用.

Unfortunatelly it dosent work.

我的 IDE 显示错误:

My IDE shows me errors:

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

请告诉我我做错了什么.

Please tell me what I am doing wrong.

推荐答案

是的,这对您有用,但您需要在 RequestContext 上为您需要的所有不同类型添加 @ExtraTypes 注释.

Yes this will work for you but you need to have the @ExtraTypes annotation on your RequestContext for all the different types you will need.

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

I posted a full example a while back.

带有@ExtraTypes 的GWT 多态列表

编辑

要让它工作,你应该让你的通用请求上下文使用泛型.这是我过去所做的,它对我来说是正确的.您不需要泛型上的额外类型来完成这项工作,因为您将告诉它类型.

To get this to work you should make your generic requestcontext use generics. This is what I have done in the past and it works correctly for me. You won't need the extra types on the generic to make this work because you are going to be telling it the type.

@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);
}

我前段时间发现了一个问题,不确定是否已修复,但我还必须将方法添加到扩展类中.我不介意,因为我仍然可以在需要时使用我的 GenericContext 并且一切正常.这让我可以使用 guava LoadingCache 创建一个很好的实体缓存机制.

There was a problem I found a while ago, not sure if it has been fixed but I also had to add the methods to the extending class. I didn't mind because I was still allowed to use my GenericContext when needed and everything worked. This allowed me to create a nice entity caching mechanism with 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);
    }

}

这篇关于具有泛型的类型化类的 RequestFactory 客户端继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆