1
//$Id: Versioning.java 10858 2006-11-21 23:28:29Z steve.ebersole@jboss.com $
2
package org.hibernate.engine;
4
import org.apache.commons.logging.Log;
5
import org.apache.commons.logging.LogFactory;
7
import org.hibernate.persister.entity.EntityPersister;
8
import org.hibernate.type.VersionType;
11
* Utilities for dealing with optimisitic locking values.
15
public final class Versioning {
17
* Apply no optimistic locking
19
public static final int OPTIMISTIC_LOCK_NONE = -1;
22
* Apply optimisitc locking based on the defined version or timestamp
25
public static final int OPTIMISTIC_LOCK_VERSION = 0;
28
* Apply optimisitc locking based on the a current vs. snapshot comparison
29
* of <b>all</b> properties.
31
public static final int OPTIMISTIC_LOCK_ALL = 2;
34
* Apply optimisitc locking based on the a current vs. snapshot comparison
35
* of <b>dirty</b> properties.
37
public static final int OPTIMISTIC_LOCK_DIRTY = 1;
39
private static final Log log = LogFactory.getLog( Versioning.class );
42
* Private constructor disallowing instantiation.
44
private Versioning() {}
47
* Create an initial optimisitc locking value according the {@link VersionType}
48
* contract for the version property.
50
* @param versionType The version type.
51
* @param session The originating session
52
* @return The initial optimisitc locking value
54
private static Object seed(VersionType versionType, SessionImplementor session) {
55
Object seed = versionType.seed( session );
56
if ( log.isTraceEnabled() ) log.trace("Seeding: " + seed);
61
* Create an initial optimisitc locking value according the {@link VersionType}
62
* contract for the version property <b>if required</b> and inject it into
65
* @param fields The current snapshot state
66
* @param versionProperty The index of the version property
67
* @param versionType The version type
68
* @param session The orginating session
69
* @return True if we injected a new version value into the fields array; false
72
public static boolean seedVersion(
75
VersionType versionType,
76
SessionImplementor session) {
77
Object initialVersion = fields[versionProperty];
79
initialVersion==null ||
80
// This next bit is to allow for both unsaved-value="negative"
81
// and for "older" behavior where version number did not get
82
// seeded if it was already set in the object
83
// TODO: shift it into unsaved-value strategy
84
( (initialVersion instanceof Number) && ( (Number) initialVersion ).longValue()<0 )
86
fields[versionProperty] = seed( versionType, session );
90
if ( log.isTraceEnabled() ) {
91
log.trace( "using initial version: " + initialVersion );
99
* Generate the next increment in the optimisitc locking value according
100
* the {@link VersionType} contract for the version property.
102
* @param version The current version
103
* @param versionType The version type
104
* @param session The originating session
105
* @return The incremented optimistic locking value.
107
public static Object increment(Object version, VersionType versionType, SessionImplementor session) {
108
Object next = versionType.next( version, session );
109
if ( log.isTraceEnabled() ) {
112
versionType.toLoggableString( version, session.getFactory() ) +
114
versionType.toLoggableString( next, session.getFactory() )
121
* Inject the optimisitc locking value into the entity state snapshot.
123
* @param fields The state snapshot
124
* @param version The optimisitc locking value
125
* @param persister The entity persister
127
public static void setVersion(Object[] fields, Object version, EntityPersister persister) {
128
if ( !persister.isVersioned() ) {
131
fields[ persister.getVersionProperty() ] = version;
135
* Extract the optimisitc locking value out of the entity state snapshot.
137
* @param fields The state snapshot
138
* @param persister The entity persister
139
* @return The extracted optimisitc locking value
141
public static Object getVersion(Object[] fields, EntityPersister persister) {
142
if ( !persister.isVersioned() ) {
145
return fields[ persister.getVersionProperty() ];
149
* Do we need to increment the version number, given the dirty properties?
151
* @param dirtyProperties The array of property indexes which were deemed dirty
152
* @param hasDirtyCollections Were any collections found to be dirty (structurally changed)
153
* @param propertyVersionability An array indicating versionability of each property.
154
* @return True if a version increment is required; false otherwise.
156
public static boolean isVersionIncrementRequired(
157
final int[] dirtyProperties,
158
final boolean hasDirtyCollections,
159
final boolean[] propertyVersionability) {
160
if ( hasDirtyCollections ) {
163
for ( int i = 0; i < dirtyProperties.length; i++ ) {
164
if ( propertyVersionability[ dirtyProperties[i] ] ) {