Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session

Hibernate version property not updated on client side

Avatar

Level 2

Hi,

I created a custom Assembler extending from AbstractAssembler. The Assembler itself uses JPA 1.0 with Hibernate Annotations and Hibernate EntityManager. The entities all have a version property that is annotated with @Version and a corresponding column for the version in their database table.

The problem is: when an entity gets updated on the client (e.g. entity.name changes from "A" to "B") and the change gets committed, the data gets correctly stored in the database and the version property gets increased by one by Hibernate (e.g. entity.version was 1 and after the update in the database entity.version is 2).

However, the change of the version is not transferred back to the clients. This leads to stale / incorrect data on the client as the version is always incorrect. So the next time a client changes data in that entity and commits it, Hibernate will throw an OptimisticLockException as the version numbers do not match any more.

The only idea I came up with so far is to manually tell LCDS about this by getting the DataServiceTransaction withing the update method of the assembler and then propagate the change after the call to entityManager.merge() - but this seems a bit overkill to me.

Any ideas?

Dirk.

3 Replies

Avatar

Employee

Any server side changes have to be registered with LCDS to get sent out to the clients.  So in this case a simple call to DataServiceTransaction.updateItem() is needed, after your database commit is completed on the server.

Avatar

Level 2

So as the updateItem() method requires an String[] of the names of the properties changed for that update, do I need to pass over all changed properties (those changed on the client plus those changed on the server) or it enough to just propagate the one property (version) that has been changed in the persistence layer?

E.g.

// this is the update Method which is called by the Assembler

// changes is the List of changed properties as provided by the Assembler

public T updateItem(T newVersion, T previousVersion, List<String> changes)

{

  // merge the entity

  newVersion = entityManager.merge(newVersion);

  entityManager.flush();

  // after this merge / flush the version value will be increased and un-synced with the LCDS object state

  DataServiceTransaction tx = DataServiceTransaction.getCurrentDataServiceTransaction();

  // is this enough? Or do I need to add all properties (including those from the changes List?)

  String[] properties = new String[1];

  properties[0] = "version";

  String destination = newVersion.getClass().getSimpleName();

  tx.updateItem(destination, newVersion, previousVersion, properties);

  return newVersion;

}

Thanks,

Dirk.

Avatar

Employee

You want to send *all* the changed properties: those coming from the client and any additional properties that were changed on the server.  Also, send the latest version of the object, as it looks like you have.

This capability propagates all changes to all listening clients, in addition to flagging any potential conflicts on the generating client when the acknowledge message is sent back.

It is described in JavaDoc here:

http://help.adobe.com/en_US/LiveCycleDataServicesES/3.1/Javadoc/flex/data/assemblers/AbstractAssembl...
“Your updateItem method can modify changes sent in from the client and add additional properties.  To do this you update properties in the newVersion and add additional property names to the changes property.”