I think the preamble of my use case cluttered my actual point, so I am restating more succinctly: Why can't @Version
take a generator and allow me to assign a sequence to it like I can do for @Id
; something like this
@Entity
@javax.persistence.SequenceGenerator(
name="SEQ_STORE",
sequenceName="my_sequence"
)
public class Store implements Serializable {
private Long version;
@Version @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
public Long getVersion() { return version; }
}
But you can't do this in JPA or Hibernate. Hibernate implements @Version
as a simple incremented value 0,1,2...(or timestamp). My point here is I see this as a simple and acceptable use case. Does anyone know why this is not possible to implement in the JPA spec or by Hibernate extension?
EDIT: In my use case was peculiar in that I am using a temporal star schema where Hibernate interfaces via views and triggers do the actual save/update/delete in the fact/dimension tables. The dimension tables act like "log" tables so a snapshot may look like this from table_name:
ID ENTRY_VALUE TIME_START TIME_COMPLETE PARENT_IS
1 22 10/23/2003 1:38 10/23/2003 1:56 -1
1 23 10/23/2003 1:56 10/23/2003 2:00 22
1 24 10/23/2003 2:00 10/23/2003 2:04 24
What Hibernate would see is a view based on this sql
create view domain_object as select ... from table_name t inner join fact_table f on f.id = t.id where t.time_complete is null
So the 3 rows above represent the lifecycle of a domain object with ID 1. It was created in entry_value 22, updated in 23 and deleted in 24. If I used entry_value as @Version
then when i add another domain object say with ID 2 then version numbers start over like this
ID ENTRY_VALUE TIME_START TIME_COMPLETE PARENT_IS
1 0 10/23/2003 1:38 10/23/2003 1:56 -1
1 1 10/23/2003 1:56 10/23/2003 2:00 22
1 2 10/23/2003 2:00 10/23/2003 2:04 24
2 0 10/23/2003 2:40 null 24
PARENT_IS is invalid in this case, we need to create another column to accommodate the PARENT_IS relation.
So my ultimate point is when Hibernate does an update it goes like this
update table_name set column_name = 10, version_col_name = 2 where column_name = 3 and version_col_name = 1
Checking the version and then updating are 2 semantically diff operations, for optimistic locking all the query cares about is finding version_col_name = 1
, if that doesn't exist we get an OptimisticLockException
. Updating the version_col_name by incrementing it by 1 is totally secondary to the optimistic locking act and becomes relevant to to the succeeding update. So in a case like mine I would have liked to implement @Version
with a sequence as my use case does not keep updating a single row continuously as is the norm.