1 package org.hibernate.engine; 3 4 import org.hibernate.action.EntityInsertAction; 5 import org.hibernate.action.EntityDeleteAction; 6 import org.hibernate.action.Executable; 7 import org.hibernate.action.EntityUpdateAction; 8 import org.hibernate.action.CollectionRecreateAction; 9 import org.hibernate.action.CollectionRemoveAction; 10 import org.hibernate.action.CollectionUpdateAction; 11 import org.hibernate.action.EntityIdentityInsertAction; 12 import org.hibernate.action.BulkOperationCleanupAction; 13 import org.hibernate.HibernateException; 14 import org.hibernate.AssertionFailure; 15 import org.hibernate.cache.CacheException; 16 import org.apache.commons.logging.Log; 17 import org.apache.commons.logging.LogFactory; 18 19 import java.util.ArrayList ; 20 import java.util.List ; 21 import java.util.Set ; 22 import java.io.ObjectInputStream ; 23 import java.io.IOException ; 24 import java.io.Serializable ; 25 26 35 public class ActionQueue implements Serializable { 36 37 private static final Log log = LogFactory.getLog( ActionQueue.class ); 38 private static final int INIT_QUEUE_LIST_SIZE = 5; 39 40 private SessionImplementor session; 41 42 private ArrayList insertions; 46 private ArrayList deletions; 47 private ArrayList updates; 48 private ArrayList collectionCreations; 53 private ArrayList collectionUpdates; 54 private ArrayList collectionRemovals; 55 56 private transient ArrayList executions; 57 58 63 public ActionQueue(SessionImplementor session) { 64 this.session = session; 65 66 insertions = new ArrayList ( INIT_QUEUE_LIST_SIZE ); 67 deletions = new ArrayList ( INIT_QUEUE_LIST_SIZE ); 68 updates = new ArrayList ( INIT_QUEUE_LIST_SIZE ); 69 70 collectionCreations = new ArrayList ( INIT_QUEUE_LIST_SIZE ); 71 collectionRemovals = new ArrayList ( INIT_QUEUE_LIST_SIZE ); 72 collectionUpdates = new ArrayList ( INIT_QUEUE_LIST_SIZE ); 73 74 executions = new ArrayList ( INIT_QUEUE_LIST_SIZE * 3 ); 75 } 76 77 private void readObject(ObjectInputStream ois) throws IOException , ClassNotFoundException { 78 ois.defaultReadObject(); 79 executions = new ArrayList ( INIT_QUEUE_LIST_SIZE * 3 ); 80 } 81 82 public void clear() { 83 updates.clear(); 84 insertions.clear(); 85 deletions.clear(); 86 87 collectionCreations.clear(); 88 collectionRemovals.clear(); 89 collectionUpdates.clear(); 90 } 91 92 public void addAction(EntityInsertAction action) { 93 insertions.add( action ); 94 } 95 96 public void addAction(EntityDeleteAction action) { 97 deletions.add( action ); 98 } 99 100 public void addAction(EntityUpdateAction action) { 101 updates.add( action ); 102 } 103 104 public void addAction(CollectionRecreateAction action) { 105 collectionCreations.add( action ); 106 } 107 108 public void addAction(CollectionRemoveAction action) { 109 collectionRemovals.add( action ); 110 } 111 112 public void addAction(CollectionUpdateAction action) { 113 collectionUpdates.add( action ); 114 } 115 116 public void addAction(EntityIdentityInsertAction insert) { 117 insertions.add( insert ); 118 } 119 120 public void addAction(BulkOperationCleanupAction cleanupAction) { 121 executions.add( cleanupAction ); 123 } 124 125 130 public void executeInserts() throws HibernateException { 131 executeActions( insertions ); 132 } 133 134 139 public void executeActions() throws HibernateException { 140 executeActions( insertions ); 141 executeActions( updates ); 142 executeActions( collectionRemovals ); 143 executeActions( collectionUpdates ); 144 executeActions( collectionCreations ); 145 executeActions( deletions ); 146 } 147 148 153 public void prepareActions() throws HibernateException { 154 prepareActions( collectionRemovals ); 155 prepareActions( collectionUpdates ); 156 prepareActions( collectionCreations ); 157 } 158 159 164 public void afterTransactionCompletion(boolean success) { 165 int size = executions.size(); 166 final boolean invalidateQueryCache = session.getFactory().getSettings().isQueryCacheEnabled(); 167 for ( int i = 0; i < size; i++ ) { 168 try { 169 Executable exec = ( Executable ) executions.get(i); 170 try { 171 exec.afterTransactionCompletion( success ); 172 } 173 finally { 174 if ( invalidateQueryCache ) { 175 session.getFactory().getUpdateTimestampsCache().invalidate( exec.getPropertySpaces() ); 176 } 177 } 178 } 179 catch (CacheException ce) { 180 log.error( "could not release a cache lock", ce ); 181 } 183 catch (Exception e) { 184 throw new AssertionFailure( "Exception releasing cache locks", e ); 185 } 186 } 187 executions.clear(); 188 } 189 190 197 public boolean areTablesToBeUpdated(Set tables) { 198 return areTablesToUpdated( updates, tables ) || 199 areTablesToUpdated( insertions, tables ) || 200 areTablesToUpdated( deletions, tables ) || 201 areTablesToUpdated( collectionUpdates, tables ) || 202 areTablesToUpdated( collectionCreations, tables ) || 203 areTablesToUpdated( collectionRemovals, tables ); 204 } 205 206 public boolean areInsertionsOrDeletionsQueued() { 207 return ( insertions.size() > 0 || deletions.size() > 0 ); 208 } 209 210 private static boolean areTablesToUpdated(List executables, Set set) { 211 int size = executables.size(); 212 for ( int j = 0; j < size; j++ ) { 213 Serializable [] spaces = ( (Executable) executables.get(j) ).getPropertySpaces(); 214 for ( int i = 0; i < spaces.length; i++ ) { 215 if ( set.contains( spaces[i] ) ) { 216 if ( log.isDebugEnabled() ) log.debug( "changes must be flushed to space: " + spaces[i] ); 217 return true; 218 } 219 } 220 } 221 return false; 222 } 223 224 private void executeActions(List list) throws HibernateException { 225 int size = list.size(); 226 for ( int i = 0; i < size; i++ ) { 227 execute( (Executable) list.get(i) ); 228 } 229 list.clear(); 230 session.getBatcher().executeBatch(); 231 } 232 233 public void execute(Executable executable) { 234 final boolean lockQueryCache = session.getFactory().getSettings().isQueryCacheEnabled(); 235 if ( executable.hasAfterTransactionCompletion() || lockQueryCache ) { 236 executions.add( executable ); 237 } 238 if (lockQueryCache) { 239 session.getFactory() 240 .getUpdateTimestampsCache() 241 .preinvalidate( executable.getPropertySpaces() ); 242 } 243 executable.execute(); 244 } 245 246 private void prepareActions(List queue) throws HibernateException { 247 int size = queue.size(); 248 for ( int i=0; i<size; i++ ) { 249 Executable executable = ( Executable ) queue.get(i); 250 executable.beforeExecutions(); 251 } 252 } 253 254 259 public String toString() { 260 return new StringBuffer () 261 .append("ActionQueue[insertions=").append(insertions) 262 .append(" updates=").append(updates) 263 .append(" deletions=").append(deletions) 264 .append(" collectionCreations=").append(collectionCreations) 265 .append(" collectionRemovals=").append(collectionRemovals) 266 .append(" collectionUpdates=").append(collectionUpdates) 267 .append("]") 268 .toString(); 269 } 270 271 public int numberOfCollectionRemovals() { 272 return collectionRemovals.size(); 273 } 274 275 public int numberOfCollectionUpdates() { 276 return collectionUpdates.size(); 277 } 278 279 public int numberOfCollectionCreations() { 280 return collectionCreations.size(); 281 } 282 283 public int numberOfDeletions() { 284 return deletions.size(); 285 } 286 287 public int numberOfUpdates() { 288 return updates.size(); 289 } 290 291 public int numberOfInsertions() { 292 return insertions.size(); 293 } 294 295 public void sortCollectionActions() { 296 if ( session.getFactory().getSettings().isOrderUpdatesEnabled() ) { 297 java.util.Collections.sort( collectionCreations ); 299 java.util.Collections.sort( collectionUpdates ); 300 java.util.Collections.sort( collectionRemovals ); 301 } 302 } 303 304 public void sortUpdateActions() { 305 if ( session.getFactory().getSettings().isOrderUpdatesEnabled() ) { 306 java.util.Collections.sort( updates ); 308 } 309 } 310 311 public ArrayList cloneDeletions() { 312 return (ArrayList ) deletions.clone(); 313 } 314 315 public void clearFromFlushNeededCheck(int previousCollectionRemovalSize) { 316 collectionCreations.clear(); 317 collectionUpdates.clear(); 318 updates.clear(); 319 for ( int i = collectionRemovals.size()-1; i >= previousCollectionRemovalSize; i-- ) { 322 collectionRemovals.remove(i); 323 } 324 } 325 326 public boolean hasAnyQueuedActions() { 327 return updates.size() > 0 || 328 insertions.size() > 0 || 329 deletions.size() > 0 || 330 collectionUpdates.size() > 0 || 331 collectionRemovals.size() > 0 || 332 collectionCreations.size() > 0; 333 } 334 } 335 | Popular Tags |