~ubuntu-branches/ubuntu/wily/libhibernate3-java/wily-proposed

« back to all changes in this revision

Viewing changes to src/org/hibernate/engine/Versioning.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2007-10-14 14:43:34 UTC
  • Revision ID: james.westby@ubuntu.com-20071014144334-eamc8i0q10gs1aro
Tags: upstream-3.2.5
ImportĀ upstreamĀ versionĀ 3.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//$Id: Versioning.java 10858 2006-11-21 23:28:29Z steve.ebersole@jboss.com $
 
2
package org.hibernate.engine;
 
3
 
 
4
import org.apache.commons.logging.Log;
 
5
import org.apache.commons.logging.LogFactory;
 
6
 
 
7
import org.hibernate.persister.entity.EntityPersister;
 
8
import org.hibernate.type.VersionType;
 
9
 
 
10
/**
 
11
 * Utilities for dealing with optimisitic locking values.
 
12
 * 
 
13
 * @author Gavin King
 
14
 */
 
15
public final class Versioning {
 
16
        /**
 
17
         * Apply no optimistic locking
 
18
         */
 
19
        public static final int OPTIMISTIC_LOCK_NONE = -1;
 
20
 
 
21
        /**
 
22
         * Apply optimisitc locking based on the defined version or timestamp
 
23
         * property.
 
24
         */
 
25
        public static final int OPTIMISTIC_LOCK_VERSION = 0;
 
26
 
 
27
        /**
 
28
         * Apply optimisitc locking based on the a current vs. snapshot comparison
 
29
         * of <b>all</b> properties.
 
30
         */
 
31
        public static final int OPTIMISTIC_LOCK_ALL = 2;
 
32
 
 
33
        /**
 
34
         * Apply optimisitc locking based on the a current vs. snapshot comparison
 
35
         * of <b>dirty</b> properties.
 
36
         */
 
37
        public static final int OPTIMISTIC_LOCK_DIRTY = 1;
 
38
 
 
39
        private static final Log log = LogFactory.getLog( Versioning.class );
 
40
 
 
41
        /**
 
42
         * Private constructor disallowing instantiation.
 
43
         */
 
44
        private Versioning() {}
 
45
 
 
46
        /**
 
47
         * Create an initial optimisitc locking value according the {@link VersionType}
 
48
         * contract for the version property.
 
49
         *
 
50
         * @param versionType The version type.
 
51
         * @param session The originating session
 
52
         * @return The initial optimisitc locking value
 
53
         */
 
54
        private static Object seed(VersionType versionType, SessionImplementor session) {
 
55
                Object seed = versionType.seed( session );
 
56
                if ( log.isTraceEnabled() ) log.trace("Seeding: " + seed);
 
57
                return seed;
 
58
        }
 
59
 
 
60
        /**
 
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
 
63
         * the snapshot state.
 
64
         *
 
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
 
70
         * otherwise.
 
71
         */
 
72
        public static boolean seedVersion(
 
73
                Object[] fields,
 
74
                int versionProperty,
 
75
                VersionType versionType,
 
76
                SessionImplementor session) {
 
77
                Object initialVersion = fields[versionProperty];
 
78
                if (
 
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 )
 
85
                ) {
 
86
                        fields[versionProperty] = seed( versionType, session );
 
87
                        return true;
 
88
                }
 
89
                else {
 
90
                        if ( log.isTraceEnabled() ) {
 
91
                                log.trace( "using initial version: " + initialVersion );
 
92
                        }
 
93
                        return false;
 
94
                }
 
95
        }
 
96
 
 
97
 
 
98
        /**
 
99
         * Generate the next increment in the optimisitc locking value according
 
100
         * the {@link VersionType} contract for the version property.
 
101
         *
 
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.
 
106
         */
 
107
        public static Object increment(Object version, VersionType versionType, SessionImplementor session) {
 
108
                Object next = versionType.next( version, session );
 
109
                if ( log.isTraceEnabled() ) {
 
110
                        log.trace(
 
111
                                        "Incrementing: " +
 
112
                                        versionType.toLoggableString( version, session.getFactory() ) +
 
113
                                        " to " +
 
114
                                        versionType.toLoggableString( next, session.getFactory() )
 
115
                        );
 
116
                }
 
117
                return next;
 
118
        }
 
119
 
 
120
        /**
 
121
         * Inject the optimisitc locking value into the entity state snapshot.
 
122
         *
 
123
         * @param fields The state snapshot
 
124
         * @param version The optimisitc locking value
 
125
         * @param persister The entity persister
 
126
         */
 
127
        public static void setVersion(Object[] fields, Object version, EntityPersister persister) {
 
128
                if ( !persister.isVersioned() ) {
 
129
                        return;
 
130
                }
 
131
                fields[ persister.getVersionProperty() ] = version;
 
132
        }
 
133
 
 
134
        /**
 
135
         * Extract the optimisitc locking value out of the entity state snapshot.
 
136
         *
 
137
         * @param fields The state snapshot
 
138
         * @param persister The entity persister
 
139
         * @return The extracted optimisitc locking value
 
140
         */
 
141
        public static Object getVersion(Object[] fields, EntityPersister persister) {
 
142
                if ( !persister.isVersioned() ) {
 
143
                        return null;
 
144
                }
 
145
                return fields[ persister.getVersionProperty() ];
 
146
        }
 
147
 
 
148
        /**
 
149
         * Do we need to increment the version number, given the dirty properties?
 
150
         *
 
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.
 
155
         */
 
156
        public static boolean isVersionIncrementRequired(
 
157
                        final int[] dirtyProperties,
 
158
                        final boolean hasDirtyCollections,
 
159
                        final boolean[] propertyVersionability) {
 
160
                if ( hasDirtyCollections ) {
 
161
                        return true;
 
162
                }
 
163
                for ( int i = 0; i < dirtyProperties.length; i++ ) {
 
164
                        if ( propertyVersionability[ dirtyProperties[i] ] ) {
 
165
                                return true;
 
166
                        }
 
167
                }
 
168
            return false;
 
169
        }
 
170
 
 
171
 
 
172
}