Objectify List<Ref<T>> 未由 Google App Engine 端点序列化



嗨,有两个相关实体:客户和汽车。每个客户都可以拥有几辆汽车

这是实体的摘要视图:

public class Customer 
{
    //Inner classes for partial loads
    public static class NoCars{}
    @Id protected String id;
    private String fullName;
    @Load(unless=NoCars.class) private List<Ref<Car>> cars;
}
public class Car
{
    @Id private Long id;
    private String makeAndModel;
    private String plateNumber;
}

这是一种从数据存储中检索客户的方法

public Customer getCustomer(@Named("id") String customerId)
{
    Customer customer =  ofy().load().type(Customer.class).id(customerId).now();
    if (customer==null)
        throw new NotFoundException("customer not found");
    else
        return customer;
}

endpoints.sh不能实现此问题,因为不支持返回类型 customer 中的类型 List <Ref<Car>> ,但我发现这个有趣的解决方法:

我创建了类 customerpojo

public class CustomerPOJO
{
    private String fullName;
}

并修改了类 Customer 从中延伸

public class Customer extends CustomerPOJO
{
    //Inner classes for partial loads
    public static class NoCars{}
    @Id protected String id;
    @Load(unless=NoCars.class) private List<Ref<Car>> cars = new ArrayList<>();
}

和getter方法为:

public CustomerPOJO getCustomer(@Named("id") String customerId)
{
    Customer customer =  ofy().load().type(Customer.class).id(customerId).now();
    if (customer==null)
        throw new NotFoundException("customer not found");
    else
        return customer;
}

请注意,该方法将 CustomerPOJO 称为返回类型,但实际上返回了"完整" Customer !!!

这在Appengine 1.8.0 Objectify 4.0 RC2 中起作用。它获取客户数据以及他拥有的所有汽车( makeAndModel plateNumber )。

升级到1.8.9之后,问题出现。endpoints.sh仍然有效,因为返回类型是完全兼容的,但是在运行时我会得到一个例外,当将客户objecto解析为json。

java.io.ioexception: com.google.appengine.repackaged.org.codehaus.jackson.map.jsonmappingexception: 直接的自我参考导致循环(通过参考链: entity.customer [" cars"] -> java.util.arraylist [0] -> com.googlecode.obigndify.impl.ref.ref.ref.liveref [" key" key''] -> com.googlecode.obigne.obigndify.key [)

在1.8.9中工作的其他解决方法?@apitransformer是唯一的选择吗?

解决方案非常简单...只需隐藏参考字段即可。现在,它确实为API消费者提供了任何价值,并且只是为解析器造成麻烦:

我替换了List<Ref<Car>> getter和setter:

public List<Car> getCars()
{
    List<Car> ret = new ArrayList<>();
    Iterator<Ref<Car>> it = cars.iterator();
    while (it.hasNext())
        ret.add(it.next().getValue());
    return ret;
}
public void setCars(List<Car> newCars)
{
    Iterator<Car> it = newCars.iterator();
    while (it.hasNext())
        addCar(it.next());
}

这就是全部

最新更新