2015-11-27 32 views
1

我想知道,是否有可能使用泛型类的请求工厂代理/上下文来处理所有实体的常见操作,如getById(Long id)RequestFactory用泛型类型化类的客户端继承

在我的应用程序,我将有很多的字典类相似,那将只有idname参数,所以我想一次编写功能,并在其他类中使用它通过继承:

这里是服务器实现:

领域模型类

@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类

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

} 

下面是客户端执行实施:

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,版本,名称。

不幸的是它dosent工作。

我的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 

以下是编译错误:

[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 

请告诉我,我做错了。

回答

1

是的,这会适用于您,但您需要在您的RequestContext上为所有您需要的不同类型注册@ExtraTypes注释。

我之前发布了一个完整的示例。

GWT polymorphic lists with @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); 
} 

有,我发现前一阵子出了问题,不知道这是否已被固定,但我也不得不方法添加到扩展的类。我不介意,因为我仍然可以在需要时使用我的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); 
    } 

} 
+0

嘿。我已经添加了'@ ExtraTypes'注释,就像你告诉我的,但不幸的是它没有帮助。请检查我的帖子,我已经更新了。 – masterdany88

+0

缓存类非常有趣。你可以发布客户端的代码吗?你如何创建工厂并调用泛型方法?你能发布上下文类的代码吗?我可以编译它。 – masterdany88