【问题标题】:GWT Autobean frozen when saving graph保存图形时 GWT Autobean 冻结
【发布时间】:2012-06-05 02:32:16
【问题描述】:

我正在使用带有编辑器和请求工厂框架的 GWT 2.4。我有一个模型,Trip,它有一个地址“来源”和一个地址“目的地”。通过 UI 创建行程时,会自动创建两个地址并分配给行程。用户填写详细信息并保存。出于某种原因,我在尝试坚持到服务器时收到“autobean freeze 错误”。此代码在 GWT 2.3 中有效,我无法切换回来。我希望它不是 GWT 2.4 中的错误。这是我正在做的一些示例代码:

RequestContext request = requestFactory.request();
TripProxy trip = request.create(TripProxy.class);
trip.setOrigin(request.create(AddressProxy.class));
trip.setDestination(request.create(AddressProxy.class));
driver.edit(trip, request);
this.trip = trip;

// … on save button clicked (different method)

RequestContext request = driver.flush();
request.save(trip).with(driver.getPaths()).fire(someReceiverImpl);

结果:

java.lang.IllegalStateException: The AutoBean has been frozen
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.checkFrozen(AbstractAutoBean.java:195)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.setProperty(AbstractAutoBean.java:270)
at sun.reflect.GeneratedMethodAccessor53.invoke(Unknown Source)

fire 的调用成功完成,但在requestfactory 中的某处,抛出了上述错误。奇怪的是,实体保存在服务器上,但不强制执行验证。当我简化模型并删除地址关联时,验证和保存工作。我的主要问题是 autobean freeze 错误;验证是次要的。

编辑:在进一步调查中,我发现实体可以正常进入服务器并按预期持续存在。它在返回时抛出上述异常。 AddressProxy 是一个 ValueProxy,看起来 RF 不喜欢 Trip 带着这些关联回来。返回 null '修复'问题,但这显然不会长期工作。

【问题讨论】:

    标签: java gwt gwt2 requestfactory


    【解决方案1】:

    我知道这比您要求的要多得多,但是这 3 个技巧帮助了我(来自here):

    1. 尝试编辑锁定的实体。

      如果实体被冻结(锁定更改),您不能:

      • 更改其属性

      • 在 requestContext 方法调用中使用它。

      如果你尝试这样做,你会收到异常:java.lang.IllegalStateException: The AutoBean has been freeze.

      实体何时可能被冻结?

      • 作为响应返回的每个实体都被冻结

      • 在 requestContext 调用中使用的每个实体都将被冻结。

      在第一种情况下,解决方案很简单——你只需要解锁给定的实体。为此,您必须使用 RequestContext 类的实例并调用 edit() 方法。

      StudentRequest req1 = requestFactory.studentRequest();  
      StudentProxy s2 = req1.edit(s1);
      

      在第二种情况下,你不应该再使用给定的实体,它不能被编辑,因为它已经分配了一个 requestContext。如果您想更改它,您必须再次从服务器检索此实体的实例并按照 a) 点的说明进行操作。

    2. 尝试在已分配 requestContext 的实体上调用 requestContext.edit()。

      如果您已从服务器检索实体或创建了新实体,然后您尝试使用 ANOTHER RequestContext 对其进行编辑,例如这样:

      StudentRequest req = requestFactory.studentRequest();
      s1 = req.create(StudentProxy.class);
      // s1 is connected with "req" and one context is just enough for it
      StudentRequest reqZZZ = requestFactory.studentRequest();
      reqZZZ.edit(s1); // you cannot do it - here exception will be thrown
      

      你肯定会收到一个例外:

      java.lang.IllegalArgumentException:试图编辑之前由另一个 RequestContext 编辑过的 EntityProxy

      在您有一个 bean 的情况下,您可能会遇到这个问题,但是您没有跟踪在之前的某个方法调用中创建或编辑了 bean 的请求上下文。在这种情况下,您必须将先前的 requestContext 保存在某处,或者将其与实体一起发送到感兴趣的点。最好的解决方案可能是创建一些特殊的层来保存当前使用的请求。

    3. 尝试重用已触发的请求上下文。

      您可以使用请求上下文来创建和编辑许多不同的实体(也属于不同的类型)。您还可以累积应该触发的方法。但是你不能做的是尝试使用它两次来触发请求。如果您创建了一个请求并在其上调用了 fire() 方法,则不能再执行此操作。如果你这样做,你会得到:java.lang.IllegalStateException:A request is already in progress 异常。

      解决方案是简单地创建一个新的 requestContext。

    【讨论】:

      【解决方案2】:

      这是由于服务器上没有使用相同的 EntityManager 造成的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多