RequestFactory实体的参数:List< OfOtherEntity>在客户端上为空。在服务器上是好的 [英] RequestFactory Entity's parameter: List<OfOtherEntity> is null on client. On server is ok

查看:126
本文介绍了RequestFactory实体的参数:List< OfOtherEntity>在客户端上为空。在服务器上是好的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习RequestFactory。我有一个简单的例子工作。现在我想从下面为RF实现这些实体:




服务器包

  @Entity 
public class Pizza实现可识别的,可版本化的{
@Id
@GeneratedValue = GenerationType.IDENTITY)
私人长ID;
@版本
私人长版;
私人字符串名称;
@ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
private List< Ingredient>配料;
* * Getters和Setters * /
}

@Entity
公共类成分实现可识别,可版本化{
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private长ID;
@版本
私人长版;
私人字符串名称;
私人布尔素食;
/ * Getters and Setters * /
}

这里是类为披萨实体

  @Override 
public List< Pizza> get(){

CriteriaBuilder cb = JPA.em()。getCriteriaBuilder();
CriteriaQuery< Pizza> q = cb.createQuery(Pizza.class);
Root< Pizza> c = q.from(Pizza.class);
q.select(c);

TypedQuery< Pizza> query = JPA.em()。createQuery(q);
列表< Pizza> results = query.getResultList(); (成分i:p.getIngredients()){
logger.info(i.getName());
$ b for(Pizza p:results){

}
}
返回结果;
}






共享包



我为这些类写了Proxies:

  @ProxyFor(value = Pizza.class,locator = PizzaLocator.class)
public interface PizzaProxy extends EntityProxy {
public Long getId();
public String getName();
public void setName(String name);
public Long getVersion();
public List< IngredientProxy> getIngredients();
公共无效setIngredients(列表与LT; IngredientProxy>成分)
}

@ProxyFor(值= Ingredient.class)
公共接口IngredientProxy延伸EntityProxy {
public void setId(Long id);
public Long getId();
public Long getVersion();
public void setVersion(Long version);
public String getName();
public void setName(String name);
public boolean isVegan();
public void setVegan(boolean vegan);
}

RF相关接口:

  public interface RequestFactoryServices扩展了RequestFactory {
PizzaRequest pizzaRequest();
}

@Service(value = PizzaDao.class,locator = DaoLocator.class)
public interface PizzaRequest extends RequestContext {
Request< PizzaProxy> findById(Long id);
请求<虚拟>保存(PizzaProxy披萨);
请求< List< PizzaProxy>>得到();
}






客户端包



以下是我从服务器获取数据的方式:

 列表与LT; PizzaProxy> pizzas =新的LinkedList< PizzaProxy>(); 
PizzaRequest context = createFactory()。pizzaRequest();
context.get()。to(new Receiver< List< PizzaProxy>>(){
@Override
public void onSuccess(List< PizzaProxy> response){
for (PizzaProxy p:response){
RootPanel.get()。add(new Label(
p.getId()++
p.getName()+,+
p.getVersion()+,+
p.getIngredients()
));
}
}
})。






正如您在 DAO 类中的 get()方法我正在打印记录关于配料的信息。



问题是当我调用 p.getIngredients()时,我是获得 null ,而不是 IngredientsProxies



是否发生,因为我没有Dao和Locator类为成分实体?



请帮忙。

答案:
实体关系


相关实体的更改可以保存在一个请求中。例如,GWT中的DynatableRF示例应用程序中的这段代码会同时创建一个新的Person和Address:

PersonRequest context = requestFactory.personRequest();
AddressProxy address = context.create(AddressProxy.class);
PersonProxy person = context.create(PersonProxy.class);
person.setAddress(address);
context.persist()。using(person).fire(...);
RequestFactory自动发送一个请求中的整个对象图。在这种情况下,服务器上Person.persist()的实现也负责持久化相关地址,这可能会或可能不会自动发生,具体取决于ORM框架以及如何定义关系。请注意,RequestFactory目前不支持嵌入对象(@Embedded在各种ORM框架中),因为它期望每个实体都以其自己的ID独立存在。



查询服务器时, RequestFactory不会自动填充对象图中的关系。要做到这一点,请在请求中使用with()方法,并将相关的属性名称指定为字符串:

请求findReq = requestFactory.personRequest()。find(personId )。随着( 地址);
还需要使用with()方法来检索任何带有ValueProxy类型的属性。 with()方法接受多个String参数,因此您可以一次指定多个属性名称。要指定嵌套属性,请使用点符号。放在一起,你可能有

请求findReq = find(personId).with(phone,address.city,address.zip)

解决方案

默认情况下,gwt在获取对象时不附加集合实体。您需要在您的射频请求中使用.with(成分)。确保你的比萨类有一个getIngredients方法。射频请求上下文将使用它来获取成分。如果你是从休眠状态中获取这些数据,你可能还需要确保你有一个事务处于打开状态。这将确保rf上下文可以在检索比萨配料时使用附属实体。



请注意,您不想使用with(getIngredients),rf上下文将正确调用get方法。

  context.get()。with(ingredients)。fire(new Receiver<>)


I am learning RequestFactory. I have simple example working. Now I would like to implement for RF those Entities from below:


Server package

@Entity
public class Pizza implements Identifiable, Versionable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Version
    private Long version;
    private String name;
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<Ingredient> ingredients;
    /* Getters and Setters */
}

@Entity
public class Ingredient implements Identifiable, Versionable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Version
    private Long version;
    private String name;
    private boolean vegan;
    /* Getters and Setters */
}

Here is DAO class for Pizza Entity:

@Override
public List<Pizza> get() {

    CriteriaBuilder cb = JPA.em().getCriteriaBuilder();
    CriteriaQuery<Pizza> q = cb.createQuery(Pizza.class);
    Root<Pizza> c = q.from(Pizza.class);
    q.select(c);

    TypedQuery<Pizza> query = JPA.em().createQuery(q);
    List<Pizza> results = query.getResultList();

    for(Pizza p: results) {
        for(Ingredient i: p.getIngredients()) {
            logger.info(i.getName());
        }
    }
    return results;
}


Shared package

I wrote Proxies for those classes:

@ProxyFor(value = Pizza.class, locator = PizzaLocator.class)
public interface PizzaProxy extends EntityProxy {
  public Long getId();
  public String getName();
  public void setName( String name );
  public Long getVersion();
  public List<IngredientProxy> getIngredients();
  public void setIngredients( List<IngredientProxy> ingredients )
}

@ProxyFor(value = Ingredient.class)
public interface IngredientProxy extends EntityProxy {
    public void setId(Long id);
    public Long getId();
    public Long getVersion();
    public void setVersion(Long version);
    public String getName();
    public void setName(String name);
    public boolean isVegan();
    public void setVegan(boolean vegan);
}

RF related interfaces:

public interface RequestFactoryServices extends RequestFactory {
      PizzaRequest pizzaRequest();
}

@Service(value = PizzaDao.class, locator = DaoLocator.class)
public interface PizzaRequest extends RequestContext {
    Request<PizzaProxy> findById( Long id );
    Request<Void> save( PizzaProxy pizza );
    Request<List<PizzaProxy>> get();
}


Client package

And here is the way I get data from server:

List<PizzaProxy> pizzas = new LinkedList<PizzaProxy>();
PizzaRequest context = createFactory().pizzaRequest();
context.get().to(new Receiver<List<PizzaProxy>>() {
        @Override
        public void onSuccess(List<PizzaProxy> response) {
            for(PizzaProxy p: response) {
                RootPanel.get().add(new Label(
                    p.getId() + " " + 
                    p.getName() + ", " + 
                    p.getVersion() + ", " + 
                    p.getIngredients()
                 ));
            }
        }
    }).fire();


As You can see in DAO class in get() method I am printing to logger info about ingredients. On the server side it all works.

The problem is that when I call p.getIngredients() I am getting null, instead of list of IngredientsProxies.

Is it happening cause I don't have Dao and Locator classes for Ingredients Entity?

Please help.

Answer: Entity Relationships

Changes to related entities can be persisted in a single request. For example, this code from the DynatableRF sample app in GWT trunk creates a new Person and Address at the same time:

PersonRequest context = requestFactory.personRequest(); AddressProxy address = context.create(AddressProxy.class); PersonProxy person = context.create(PersonProxy.class); person.setAddress(address); context.persist().using(person).fire(...); RequestFactory automatically sends the whole object graph in a single request. In this case, the implementation of Person.persist() on the server is responsible for persisting the related Address also, which may or may not happen automatically, depending on the ORM framework and how the relationship is defined. Note that RequestFactory does not currently support embedded objects (@Embedded in various ORM frameworks) because it expects every entity to exist independently with its own ID.

When querying the server, RequestFactory does not automatically populate relations in the object graph. To do this, use the with() method on a request and specify the related property name as a String:

Request findReq = requestFactory.personRequest().find(personId).with("address"); It is also necessary to use the with() method to retrieve any properties with types extending ValueProxy. The with() method takes multiple String arguments, so you can specify multiple property names at once. To specify nested properties, use dot notation. Putting it all together, you might have

Request findReq = find(personId).with("phone","address.city","address.zip")

解决方案

By default gwt does not attach collection entities when fetching the object. You need to use the .with("ingredients") on your rf request. Make sure you have a getIngredients method in your pizza class. The rf request context will use this to fetch the ingredients. You may also need to make sure you have a transaction open if you are fetching this from something like hibernate. This will make sure the rf context can use an attached entity when retrieving the ingredients for your pizza.

Note that you don't want to use the with("getIngredients") the rf context will call the get method correctly.

context.get().with("ingredients").fire(new Receiver<>)

这篇关于RequestFactory实体的参数:List&lt; OfOtherEntity&gt;在客户端上为空。在服务器上是好的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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