"The following types are supported for version properties: int, Integer, short, Short, long, Long, java.sql.Timestamp."

In other page (en.wikibooks.org/wiki/Java_Persistence/Locking#Optimistic_Locking) says:

Quote:

"JPA supports using an optimistic locking version field that gets updated on each update. The field can either be numeric or a timestamp value. A numeric value is recommended as a numeric value is more precise, portable, performant and easier to deal with than a timestamp."

Quote:

"Timestamp locking is frequently used if the table already has a last updated timestamp column, and is also a convenient way to auto update a last updated column. The timestamp version value can be more useful than a numeric version, as it includes the relevant information on when the object was last updated."

The questions I have are:

- Is better a Timestamp type if you are going to have a lastUpdated field or is better to have a numeric version field and the timestamp in other field?

- Between numeric types (int, Integer, short, Short, long, Long) which is the best to choose (considering the length of each type)? I mean, I think the best is Long but it requires a lot of space for each row.

- What happens when the version field gets to the last number of a numeric type (for example 32,767 in a Short field)? Will it start from 1 again in the next increment? If there is no strange behavior when this happens I think the best type for a version field would be Short as it would detect changes and requires little space.

Better is relative, and as the quotes you gave suggest, it depends on what you want it for. Timestamp gives you the time it was last updated, while a numeric value is 'recommended' - it gives you everything else. You will have to measure the difference yourself to see if the benefits of using a separate version field outweighs the cost of having an extra field. For instance, balancing enough precision in the Timestamp to handle concurrent load in your app vs using an extra field for a version and keeping lastUpdated updated. There isn't a universal answer.

The difference between numeric is the size. So again, what is best is a trade off. How many updates do you expect to occur on a single row? Which brings the answer to the next question, what happens when the value is exceeded: The best way to be certain what will happen is to try it and see. Insert a row with the version set to the max value and read and change it in JPA to see what happens. Java will roll over to a negative, but the EclipseLink internals use a long conversions, which will probably cause it to truncate to a positive 1 when converted back to shorter types, but I'm not sure. There are not likely any consequences other than some invalidation occurring when the rollover occurs if you are using cache synchronization, but I've never tested it myself.

The difference between numeric is the size. So again, what is best is a trade off. How many updates do you expect to occur on a single row? Which brings the answer to the next question, what happens when the value is exceeded: The best way to be certain what will happen is to try it and see. Insert a row with the version set to the max value and read and change it in JPA to see what happens. Java will roll over to a negative, but the EclipseLink internals use a long conversions, which will probably cause it to truncate to a positive 1 when converted back to shorter types, but I'm not sure. There are not likely any consequences other than some invalidation occurring when the rollover occurs if you are using cache synchronization, but I've never tested it myself.

Last time I checked, it blows up. I tried to track down the JPA spec but it mentions nothing as to what should happen when the value reaches the end. If the value is at MAX_(type used) EclipseLink should really roll back to zero. All these @Version columns are ticking timebombs as far as I am concerned. In reality there is very little need to go past the "short" type for the version column, assuming that the roll over happens correctly.