GWT Autobean frozen when saving graph-Collection of common programming errors

I am using GWT 2.4 with the editor and request factory frameworks. I have a model, Trip, which has an Address ‘origin’ and an Address ‘destination’. When creating a Trip via the UI, the two addresses are created automatically and assigned to the Trip. User fills out details and saves. For some reason, I am getting the ‘autobean frozen error’ when trying to persist to the server. This code worked in GWT 2.3 and I cant switch back. I am hoping its not a bug in GWT 2.4. Here is some sample code of what I am doing:

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

Results in:

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)

The call to fire completes successfully but somewhere from within requestfactory, the above error is thrown. Curiously, the entity is saved on the server however, validations are not enforced. When I simplify the model and remove the Address associations, the validation and save works. My main issue is the autobean frozen error; the validation stuff is secondary.

EDIT: On further investigation I found that the entities are making it to the server okay and persisting as expected. Its upon return that the above exception is thrown. AddressProxy is a ValueProxy and it looks like RF doesnt like Trip coming back with these associations. Returning null ‘fixes’ the problem but this obviously wont work long term.

  1. This was caused by not using the same EntityManager on the server.

  2. I know this is a lot more than you’re asking for, but these 3 tips have helped me out (from here):

    1. Trying to edit locked entity.

      If an entity is frozen ( locked for changes) you cannot:

      • change its properties

      • use it in requestContext method calls.

      If you try to do it, you will receive the exception : java.lang.IllegalStateException: The AutoBean has been frozen.

      When entity may be frozen?

      • every entity returned as a response is frozen

      • every entity which has been used in requestContext call will be frozen.

      In first situation solution is easy – you just have to unlock given entity. In order to do that you must use instance of your RequestContext class and call edit() method.

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

      In second situation you should not use given entity any more, It cannot be edited because it has already a requestContext assigned. If you want to change it you must retrieve instance of this entity from server again and follow instructions for point a).

    2. Trying to call requestContext.edit() on entity which already has a requestContext assigned.

      If you have retrieved the entity from the server or created a new one, and afterwords you are trying to use ANOTHER RequestContext to edit it e.g. in this way:

      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
      

      you will surely recieve an exception:

      java.lang.IllegalArgumentException: Attempting to edit an EntityProxy previously edited by another RequestContext

      You may run into this problem in situations where you have a bean, but you have no track of request context which has created or edited the bean in some previous method call. In this situation you must save the previous requestContext somewhere, or send it along with the entity to the point of interest. The best solution may be to create some special layer which holds currently used request.

    3. Trying to reuse a Request Context which has already been fired.

      You can use a request context to create and edit many different entities (also of a different type). You can also accumulate the methods which should be fired. But what you cannot do is to try to use it twice to fire a request. If you have created a request and call the fire() method on it, you cannot do it again. If you do you will get: java.lang.IllegalStateException:A request is already in progress exception.

      The solution is to simply create a new requestContext.