I'm using Roo 1.2.1, JPA 2, and Hibernate 3.6 connected to an MSSQL database.
I have a web service that takes JSON and parses it into an entity; obviously the @Version column is going to be 0 because the person calling the service knows nothing about it. When I call merge() the first time it works fine. The object is persisted correctly and the version column gets set to 1.But the next time I call the web service with the same data, it says the object is stale, which is technically correct since the version would always be 0.
The ID they're passing us is guaranted to be unique, so we're using that as our primary key.
I'd like to think this would be taken care of by the entity manager somehow.
So my question is: how do I handle this without loading all of the entities from the database first, then updating the fields, then re-persisting them? That seems like kind of a hack; maybe I'm going about this the wrong way?
My entity looks like this:
@RooJavaBean
@RooToString
@RooJson
@RooJpaActiveRecord(table = "MYTABLE", persistenceUnit = "myPersistenceUnit",
transactionManager = "myTransactionManager", versionField = "version", identifierColumn = "myIdField")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Entity
public class MyEntity {
@Id
@Column(name = "myIdField")
private long myIdField;
@Version
@Column(name = "version")
private long version;
@Column("myColumn")
private String someValue;
}
You have to decide if you want optimistic locking or not.
If you want to update the database with what the client sends, regardless of potential concurrent updates between the time he got the object and the time he updates it, then that means that you don't want optimistic locking, and there shouldn't be a version field in the entity.
If you want optimistic locking, then the version should be part of the merged entity. That's how the mechanism works: it checks if the saved version number is the same as the passed version number. So if you always pass 0, obviously, it will never work.
The easiest way is of course to make it part of the JSON object sent to and by the client. You could also imagine storing the version of a given entity (sent to a client for future update, so the key would be clientId-entityId) in some in-memory or in-database table, but it would be more difficult to implement.