2011-09-20 53 views
2

我正在使用编辑器和请求工厂框架的GWT 2.4。我有一个模型Trip,它有一个地址'起源'和一个地址'目的地'。当通过UI创建旅程时,这两个地址会自动创建并分配给旅程。用户填写详细信息并保存。出于某种原因,我在尝试持久保存到服务器时遇到'autobean frozen error'。此代码在GWT 2.3中工作,我不能切换回来。我希望它不是GWT 2.4中的一个bug。下面是我在做什么一些示例代码:GWT Autobean冻结时保存图

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冻结错误;验证的东西是次要的。

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

回答

0

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

14

我知道这是一个很多比你要求的,但这些技巧3已经帮了我(从here):

  1. 试图修改锁定的实体。

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

    • 更改其属性

    • 在RequestContext的方法调用中使用它。

    如果你尝试这样做,您将收到异常:java.lang.IllegalStateException:本AutoBean已被冻结。

    当实体可能被冻结?

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

    • 每一个已在RequestContext的通话被用于将被冻结实体。

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

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

    在第二种情况下,你不应该使用指定的实体的任何更多的,它不能被编辑,因为它已经分配的RequestContext。如果要更改它,则必须再次从服务器检索此实体的实例,并按照a)中的说明进行操作。

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

    如果您已从服务器检索到实体或创建了新实体,并且后缀是尝试使用另一个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:一个请求已经在进行异常。

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

+0

这是我一直在寻找的答案谢谢。 –