KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > impl > SessionImpl


1 //$Id: SessionImpl.java,v 1.150 2005/07/18 04:14:02 oneovthafew Exp $
2
package org.hibernate.impl;
3
4 import java.io.IOException JavaDoc;
5 import java.io.ObjectInputStream JavaDoc;
6 import java.io.ObjectOutputStream JavaDoc;
7 import java.io.Serializable JavaDoc;
8 import java.sql.Connection JavaDoc;
9 import java.util.Collection JavaDoc;
10 import java.util.Collections JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.HashSet JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.Map JavaDoc;
16 import java.util.Set JavaDoc;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.dom4j.Element;
21 import org.hibernate.CacheMode;
22 import org.hibernate.ConnectionReleaseMode;
23 import org.hibernate.Criteria;
24 import org.hibernate.EntityMode;
25 import org.hibernate.Filter;
26 import org.hibernate.FlushMode;
27 import org.hibernate.HibernateException;
28 import org.hibernate.Interceptor;
29 import org.hibernate.LockMode;
30 import org.hibernate.MappingException;
31 import org.hibernate.ObjectDeletedException;
32 import org.hibernate.ObjectNotFoundException;
33 import org.hibernate.Query;
34 import org.hibernate.QueryException;
35 import org.hibernate.ReplicationMode;
36 import org.hibernate.SQLQuery;
37 import org.hibernate.ScrollMode;
38 import org.hibernate.ScrollableResults;
39 import org.hibernate.Session;
40 import org.hibernate.SessionFactory;
41 import org.hibernate.Transaction;
42 import org.hibernate.TransientObjectException;
43 import org.hibernate.UnresolvableObjectException;
44 import org.hibernate.collection.PersistentCollection;
45 import org.hibernate.engine.ActionQueue;
46 import org.hibernate.engine.CollectionEntry;
47 import org.hibernate.engine.EntityEntry;
48 import org.hibernate.engine.EntityKey;
49 import org.hibernate.engine.FilterDefinition;
50 import org.hibernate.engine.PersistenceContext;
51 import org.hibernate.engine.QueryParameters;
52 import org.hibernate.engine.SessionFactoryImplementor;
53 import org.hibernate.engine.StatefulPersistenceContext;
54 import org.hibernate.engine.Status;
55 import org.hibernate.event.AutoFlushEvent;
56 import org.hibernate.event.DeleteEvent;
57 import org.hibernate.event.DirtyCheckEvent;
58 import org.hibernate.event.EventSource;
59 import org.hibernate.event.EvictEvent;
60 import org.hibernate.event.FlushEvent;
61 import org.hibernate.event.InitializeCollectionEvent;
62 import org.hibernate.event.LoadEvent;
63 import org.hibernate.event.LoadEventListener;
64 import org.hibernate.event.LockEvent;
65 import org.hibernate.event.MergeEvent;
66 import org.hibernate.event.PersistEvent;
67 import org.hibernate.event.RefreshEvent;
68 import org.hibernate.event.ReplicateEvent;
69 import org.hibernate.event.SaveOrUpdateEvent;
70 import org.hibernate.event.SessionEventListenerConfig;
71 import org.hibernate.hql.FilterTranslator;
72 import org.hibernate.hql.QuerySplitter;
73 import org.hibernate.hql.QueryTranslator;
74 import org.hibernate.jdbc.Batcher;
75 import org.hibernate.jdbc.JDBCContext;
76 import org.hibernate.loader.criteria.CriteriaLoader;
77 import org.hibernate.loader.custom.CustomLoader;
78 import org.hibernate.loader.custom.CustomQuery;
79 import org.hibernate.persister.collection.CollectionPersister;
80 import org.hibernate.persister.entity.EntityPersister;
81 import org.hibernate.persister.entity.OuterJoinLoadable;
82 import org.hibernate.pretty.MessageHelper;
83 import org.hibernate.proxy.HibernateProxy;
84 import org.hibernate.proxy.LazyInitializer;
85 import org.hibernate.stat.SessionStatistics;
86 import org.hibernate.stat.SessionStatisticsImpl;
87 import org.hibernate.tuple.DynamicMapInstantiator;
88 import org.hibernate.type.Type;
89 import org.hibernate.util.ArrayHelper;
90 import org.hibernate.util.CollectionHelper;
91 import org.hibernate.util.EmptyIterator;
92 import org.hibernate.util.JoinedIterator;
93 import org.hibernate.util.StringHelper;
94
95
96 /**
97  * Concrete implementation of a Session, and also the central, organizing component
98  * of Hibernate's internal implementation. As such, this class exposes two interfaces;
99  * Session itself, to the application, and SessionImplementor, to other components
100  * of Hibernate. This class is not threadsafe.
101  *
102  * @author Gavin King
103  */

104 public final class SessionImpl extends AbstractSessionImpl
105         implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {
106
107     // todo : need to find a clean way to handle the "event source" role
108
// a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
109
// passing around seperate references to interceptor, factory, actionQueue, and persistentContext is not manageable...
110

111     private static final Log log = LogFactory.getLog(SessionImpl.class);
112
113     private EntityMode entityMode = EntityMode.POJO;
114     private boolean autoClear; //for EJB3
115

116     private final long timestamp;
117     private boolean closed = false;
118     private FlushMode flushMode = FlushMode.AUTO;
119     private CacheMode cacheMode = CacheMode.NORMAL;
120
121     private Interceptor interceptor;
122
123     private transient int dontFlushFromFind = 0;
124
125     private ActionQueue actionQueue;
126     private StatefulPersistenceContext persistenceContext;
127     private transient JDBCContext jdbcContext;
128     private SessionEventListenerConfig listeners;
129
130     private final boolean flushBeforeCompletionEnabled;
131     private final boolean autoCloseSessionEnabled;
132     private final ConnectionReleaseMode connectionReleaseMode;
133
134     private Map JavaDoc enabledFilters = new HashMap JavaDoc();
135
136     private boolean isRootSession = true;
137     private Map JavaDoc childSessionsByEntityMode;
138
139
140     public Session getSession(EntityMode entityMode) {
141         if ( this.entityMode == entityMode ) {
142             return this;
143         }
144
145         if ( childSessionsByEntityMode == null ) {
146             childSessionsByEntityMode = new HashMap JavaDoc();
147         }
148
149         SessionImpl rtn = (SessionImpl) childSessionsByEntityMode.get( entityMode );
150         if ( rtn == null ) {
151             rtn = new SessionImpl( this, entityMode );
152             childSessionsByEntityMode.put( entityMode, rtn );
153         }
154
155         return rtn;
156     }
157
158
159     private void readObject(ObjectInputStream JavaDoc ois) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
160         log.trace("deserializing session");
161
162         interceptor = (Interceptor) ois.readObject();
163         factory = (SessionFactoryImpl) ois.readObject();
164         jdbcContext = (JDBCContext) ois.readObject();
165         ois.defaultReadObject();
166         
167         Iterator JavaDoc iter = enabledFilters.values().iterator();
168         while ( iter.hasNext() ) {
169             ( (FilterImpl) iter.next() ).afterDeserialize(factory);
170         }
171     }
172
173     private void writeObject(ObjectOutputStream JavaDoc oos) throws IOException JavaDoc {
174         if ( jdbcContext.getConnectionManager().isPhysicallyConnected() ) {
175             throw new IllegalStateException JavaDoc( "Cannot serialize a session while connected" );
176         }
177
178         log.trace( "serializing session" );
179
180         oos.writeObject(interceptor);
181         oos.writeObject(factory);
182         oos.writeObject(jdbcContext);
183         oos.defaultWriteObject();
184
185     }
186
187     public void clear() {
188         persistenceContext.clear();
189         actionQueue.clear();
190     }
191
192     private SessionImpl(SessionImpl parent, EntityMode entityMode) {
193         super(parent.factory);
194
195         this.timestamp = parent.timestamp;
196
197         this.jdbcContext = parent.jdbcContext;
198
199         this.interceptor = parent.interceptor;
200         this.listeners = parent.listeners;
201
202         this.actionQueue = new ActionQueue(this);
203
204         this.entityMode = entityMode;
205         this.persistenceContext = new StatefulPersistenceContext(this);
206         
207         this.flushBeforeCompletionEnabled = false;
208         this.autoCloseSessionEnabled = false;
209         this.connectionReleaseMode = null;
210
211         this.isRootSession = false;
212
213         if ( factory.getStatistics().isStatisticsEnabled() ) {
214             factory.getStatisticsImplementor().openSession();
215         }
216         
217         log.debug( "opened session [" + entityMode + "]" );
218     }
219
220     SessionImpl(
221             final Connection JavaDoc connection,
222             final SessionFactoryImpl factory,
223             final boolean autoclose,
224             final long timestamp,
225             final Interceptor interceptor,
226             final SessionEventListenerConfig listeners,
227             final EntityMode entityMode,
228             final boolean flushBeforeCompletionEnabled,
229             final boolean autoCloseSessionEnabled,
230             final ConnectionReleaseMode connectionReleaseMode) {
231         super(factory);
232
233         this.timestamp = timestamp;
234
235         this.entityMode = entityMode;
236
237         this.interceptor = interceptor;
238         this.listeners = listeners;
239
240         this.actionQueue = new ActionQueue( this );
241         this.persistenceContext = new StatefulPersistenceContext( this );
242
243         this.isRootSession = true;
244
245         this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
246         this.autoCloseSessionEnabled = autoCloseSessionEnabled;
247         this.connectionReleaseMode = connectionReleaseMode;
248
249         this.jdbcContext = new JDBCContext( this, connection );
250
251         if ( factory.getStatistics().isStatisticsEnabled() ) {
252             factory.getStatisticsImplementor().openSession();
253         }
254         
255         if ( log.isDebugEnabled() ) log.debug( "opened session at timestamp: " + timestamp );
256     }
257
258     public Batcher getBatcher() {
259         // TODO : should remove this exposure
260
// and have all references to the session's batcher use the ConnectionManager.
261
return jdbcContext.getConnectionManager().getBatcher();
262     }
263
264     public SessionFactoryImplementor getFactory() {
265         return factory;
266     }
267
268     public long getTimestamp() {
269         return timestamp;
270     }
271
272     public Connection JavaDoc close() throws HibernateException {
273
274         log.trace( "closing session" );
275
276         if ( factory.getStatistics().isStatisticsEnabled() )
277             factory.getStatisticsImplementor().closeSession();
278
279         try {
280             try {
281                 if ( childSessionsByEntityMode != null ) {
282                     Iterator JavaDoc childSessions = childSessionsByEntityMode.values().iterator();
283                     while ( childSessions.hasNext() ) {
284                         final SessionImpl child = ( SessionImpl ) childSessions.next();
285                         child.close();
286                     }
287                 }
288             }
289             catch( Throwable JavaDoc t ) {
290                 // just ignore
291
}
292
293             if ( isRootSession ) {
294                 return jdbcContext.getConnectionManager().close();
295             }
296             else {
297                 return null;
298             }
299         }
300         finally {
301             closed = true;
302             cleanup();
303         }
304     }
305
306     public ConnectionReleaseMode getConnectionReleaseMode() {
307         return connectionReleaseMode;
308     }
309
310     public boolean isAutoCloseSessionEnabled() {
311         return autoCloseSessionEnabled;
312     }
313
314     public boolean isOpen() {
315         return !closed;
316     }
317
318     public boolean isFlushModeNever() {
319         return getFlushMode() == FlushMode.NEVER;
320     }
321
322     public boolean isFlushBeforeCompletionEnabled() {
323         return flushBeforeCompletionEnabled;
324     }
325
326     public void managedFlush() {
327
328         log.trace("automatically flushing session");
329         flush();
330         
331         if ( childSessionsByEntityMode != null ) {
332             Iterator JavaDoc iter = childSessionsByEntityMode.values().iterator();
333             while ( iter.hasNext() ) {
334                 ( (Session) iter.next() ).flush();
335             }
336         }
337         
338     }
339
340     public boolean shouldAutoClose() {
341         return isAutoCloseSessionEnabled() && isOpen();
342     }
343
344     public void managedClose() {
345         log.trace("automatically closing session");
346         close();
347     }
348
349     public Connection JavaDoc connection() throws HibernateException {
350         return jdbcContext.connection();
351     }
352
353     public boolean isConnected() {
354         return jdbcContext.getConnectionManager().isLogicallyConnected();
355     }
356     
357     public boolean isTransactionInProgress() {
358         return jdbcContext.isTransactionInProgress();
359     }
360
361     public Connection JavaDoc disconnect() throws HibernateException {
362         log.debug( "disconnecting session" );
363         return jdbcContext.getConnectionManager().manualDisconnect();
364     }
365
366     public void reconnect() throws HibernateException {
367         log.debug( "reconnecting session" );
368         jdbcContext.getConnectionManager().manualReconnect();
369     }
370
371     public void reconnect(Connection JavaDoc conn) throws HibernateException {
372         log.debug( "reconnecting session" );
373         jdbcContext.getConnectionManager().manualReconnect( conn );
374     }
375
376     public void beforeTransactionCompletion(Transaction tx) {
377         log.trace( "before transaction completion" );
378
379         if ( isRootSession ) {
380
381             try {
382                 interceptor.beforeTransactionCompletion(tx);
383             }
384             catch (Throwable JavaDoc t) {
385                 log.error("exception in interceptor beforeTransactionCompletion()", t);
386             }
387             
388         }
389     }
390     
391     public void setAutoClear(boolean enabled) {
392         autoClear = enabled;
393     }
394     
395     /**
396      * Check if there is a Hibernate or JTA transaction in progress and,
397      * if there is not, flush if necessary, make sure the connection has
398      * been committed (if it is not in autocommit mode) and run the after
399      * completion processing
400      */

401     public void afterOperation(boolean success) {
402         if ( !jdbcContext.isTransactionInProgress() ) {
403             jdbcContext.afterNontransactionalQuery(success);
404         }
405     }
406
407     public void afterTransactionCompletion(boolean success, Transaction tx) {
408         log.trace( "after transaction completion" );
409
410         persistenceContext.afterTransactionCompletion();
411         actionQueue.afterTransactionCompletion(success);
412
413         if ( isRootSession && tx!=null ) {
414
415             try {
416                 interceptor.afterTransactionCompletion(tx);
417             }
418             catch (Throwable JavaDoc t) {
419                 log.error("exception in interceptor beforeTransactionCompletion()", t);
420             }
421             
422         }
423         
424         if (autoClear) clear();
425
426     }
427
428     /**
429      * clear all the internal collections, just
430      * to help the garbage collector, does not
431      * clear anything that is needed during the
432      * afterTransactionCompletion() phase
433      */

434     private void cleanup() {
435         persistenceContext.clear();
436     }
437
438     public LockMode getCurrentLockMode(Object JavaDoc object) throws HibernateException {
439         if ( object == null ) throw new NullPointerException JavaDoc( "null object passed to getCurrentLockMode()" );
440         if ( object instanceof HibernateProxy ) {
441             object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(this);
442             if ( object == null ) return LockMode.NONE;
443         }
444         EntityEntry e = persistenceContext.getEntry(object);
445         if ( e == null ) throw new TransientObjectException( "Given object not associated with the session" );
446         if ( e.getStatus() != Status.MANAGED ) throw new ObjectDeletedException(
447                 "The given object was deleted",
448                 e.getId(), e.getPersister().getEntityName()
449         );
450         return e.getLockMode();
451     }
452
453     public Object JavaDoc getEntityUsingInterceptor(EntityKey key) throws HibernateException {
454         // todo : should this get moved to PersistentContext?
455
// logically, is PersistentContext the "thing" to which an interceptor gets attached?
456
final Object JavaDoc result = persistenceContext.getEntity(key);
457         if ( result == null ) {
458             final Object JavaDoc newObject = interceptor.getEntity( key.getEntityName(), key.getIdentifier() );
459             if ( newObject != null ) lock(newObject, LockMode.NONE);
460             return newObject;
461         }
462         else {
463             return result;
464         }
465     }
466
467     public void saveOrUpdate(Object JavaDoc object) throws HibernateException {
468         saveOrUpdate(null, object);
469     }
470
471     public void saveOrUpdate(String JavaDoc entityName, Object JavaDoc obj) throws HibernateException {
472         SaveOrUpdateEvent event = new SaveOrUpdateEvent(entityName, obj, this);
473         listeners.getSaveOrUpdateEventListener().onSaveOrUpdate(event);
474     }
475
476     public void save(Object JavaDoc obj, Serializable JavaDoc id) throws HibernateException {
477         save(null, obj, id);
478     }
479
480     public Serializable JavaDoc save(Object JavaDoc obj) throws HibernateException {
481         return save(null, obj);
482     }
483
484     public Serializable JavaDoc save(String JavaDoc entityName, Object JavaDoc object) throws HibernateException {
485         SaveOrUpdateEvent event = new SaveOrUpdateEvent(entityName, object, this);
486         return listeners.getSaveEventListener().onSaveOrUpdate(event);
487     }
488
489     public void save(String JavaDoc entityName, Object JavaDoc object, Serializable JavaDoc id) throws HibernateException {
490         SaveOrUpdateEvent event = new SaveOrUpdateEvent(entityName, object, id, this);
491         listeners.getSaveEventListener().onSaveOrUpdate(event);
492     }
493
494     public void update(Object JavaDoc obj) throws HibernateException {
495         update(null, obj);
496     }
497
498     public void update(Object JavaDoc obj, Serializable JavaDoc id) throws HibernateException {
499         update(null, obj, id);
500     }
501
502     public void update(String JavaDoc entityName, Object JavaDoc object) throws HibernateException {
503         SaveOrUpdateEvent event = new SaveOrUpdateEvent(entityName, object, this);
504         listeners.getUpdateEventListener().onSaveOrUpdate(event);
505     }
506
507     public void update(String JavaDoc entityName, Object JavaDoc object, Serializable JavaDoc id) throws HibernateException {
508         SaveOrUpdateEvent event = new SaveOrUpdateEvent(entityName, object, id, this);
509         listeners.getUpdateEventListener().onSaveOrUpdate(event);
510     }
511
512     public void lock(Object JavaDoc object, LockMode lockMode) throws HibernateException {
513         listeners.getLockEventListener().onLock( new LockEvent(object, lockMode, this) );
514     }
515
516     public void lock(String JavaDoc entityName, Object JavaDoc object, LockMode lockMode) throws HibernateException {
517         LockEvent event = new LockEvent(entityName, object, lockMode, this);
518         listeners.getLockEventListener().onLock(event);
519     }
520
521     public void persist(String JavaDoc entityName, Object JavaDoc object, Map JavaDoc copiedAlready)
522     throws HibernateException {
523         PersistEvent event = new PersistEvent(entityName, object, this);
524         listeners.getCreateEventListener().onPersist(event, copiedAlready);
525     }
526
527     public void persist(String JavaDoc entityName, Object JavaDoc object)
528     throws HibernateException {
529         PersistEvent event = new PersistEvent(entityName, object, this);
530         listeners.getCreateEventListener().onPersist(event);
531     }
532
533     public void persist(Object JavaDoc object) throws HibernateException {
534         persist(null, object);
535     }
536
537     public Object JavaDoc merge(String JavaDoc entityName, Object JavaDoc object)
538     throws HibernateException {
539         MergeEvent event = new MergeEvent(entityName, object, this);
540         return listeners.getMergeEventListener().onMerge(event);
541     }
542
543     public Object JavaDoc merge(Object JavaDoc object) throws HibernateException {
544         return merge(null, object);
545     }
546
547     public void merge(String JavaDoc entityName, Object JavaDoc object, Map JavaDoc copiedAlready) throws HibernateException {
548         MergeEvent event = new MergeEvent(entityName, object, this);
549         listeners.getMergeEventListener().onMerge(event, copiedAlready);
550     }
551
552     public Object JavaDoc saveOrUpdateCopy(String JavaDoc entityName, Object JavaDoc object)
553     throws HibernateException {
554         MergeEvent event = new MergeEvent(entityName, object, this);
555         return listeners.getSaveOrUpdateCopyEventListener().onMerge(event);
556     }
557
558     public Object JavaDoc saveOrUpdateCopy(Object JavaDoc object) throws HibernateException {
559         return saveOrUpdateCopy(null, object);
560     }
561
562     public Object JavaDoc saveOrUpdateCopy(String JavaDoc entityName, Object JavaDoc object, Serializable JavaDoc id)
563     throws HibernateException {
564         MergeEvent event = new MergeEvent(entityName, object, id, this);
565         return listeners.getSaveOrUpdateCopyEventListener().onMerge(event);
566     }
567
568     public Object JavaDoc saveOrUpdateCopy(Object JavaDoc object, Serializable JavaDoc id)
569     throws HibernateException {
570         return saveOrUpdateCopy(null, object, id);
571     }
572
573     public void saveOrUpdateCopy(String JavaDoc entityName, Object JavaDoc object, Map JavaDoc copiedAlready)
574     throws HibernateException {
575         MergeEvent event = new MergeEvent(entityName, object, this);
576         listeners.getSaveOrUpdateCopyEventListener().onMerge(event, copiedAlready);
577     }
578
579     /**
580      * Delete a persistent object
581      */

582     public void delete(Object JavaDoc object) throws HibernateException {
583         DeleteEvent event = new DeleteEvent(object, this);
584         listeners.getDeleteEventListener().onDelete(event);
585     }
586
587     /**
588      * Delete a persistent object (by explicit entity name)
589      */

590     public void delete(String JavaDoc entityName, Object JavaDoc object) throws HibernateException {
591         DeleteEvent event = new DeleteEvent( entityName, object, this );
592         listeners.getDeleteEventListener().onDelete( event );
593     }
594
595     /**
596      * Delete a persistent object
597      */

598     public void delete(String JavaDoc entityName, Object JavaDoc object, boolean isCascadeDeleteEnabled) throws HibernateException {
599         DeleteEvent event = new DeleteEvent(entityName, object, isCascadeDeleteEnabled, this);
600         listeners.getDeleteEventListener().onDelete(event);
601     }
602
603     public void load(Object JavaDoc object, Serializable JavaDoc id) throws HibernateException {
604         LoadEvent event = new LoadEvent(id, object, this);
605         listeners.getLoadEventListener().onLoad(event, LoadEventListener.RELOAD);
606     }
607
608     public Object JavaDoc load(Class JavaDoc entityClass, Serializable JavaDoc id) throws HibernateException {
609         return load( entityClass.getName(), id );
610     }
611
612     public Object JavaDoc load(String JavaDoc entityName, Serializable JavaDoc id) throws HibernateException {
613         LoadEvent event = new LoadEvent(id, entityName, false, this);
614         boolean success = false;
615         try {
616             Object JavaDoc result = listeners.getLoadEventListener().onLoad(event, LoadEventListener.LOAD);
617             ObjectNotFoundException.throwIfNull(result, id, entityName);
618             success = true;
619             return result;
620         }
621         finally {
622             afterOperation(success);
623         }
624     }
625
626     public Object JavaDoc get(Class JavaDoc entityClass, Serializable JavaDoc id) throws HibernateException {
627         return get( entityClass.getName(), id );
628     }
629
630     public Object JavaDoc get(String JavaDoc entityName, Serializable JavaDoc id) throws HibernateException {
631         LoadEvent event = new LoadEvent(id, entityName, false, this);
632         boolean success = false;
633         try {
634             Object JavaDoc result = listeners.getLoadEventListener().onLoad(event, LoadEventListener.GET);
635             success = true;
636             return result;
637         }
638         finally {
639             afterOperation(success);
640         }
641     }
642
643     /**
644      * Load the data for the object with the specified id into a newly created object.
645      * This is only called when lazily initializing a proxy.
646      * Do NOT return a proxy.
647      */

648     public Object JavaDoc immediateLoad(String JavaDoc entityName, Serializable JavaDoc id) throws HibernateException {
649         
650         if ( log.isDebugEnabled() ) {
651             EntityPersister persister = getFactory().getEntityPersister(entityName);
652             log.debug( "initializing proxy: " + MessageHelper.infoString( persister, id, getFactory() ) );
653         }
654         
655         LoadEvent event = new LoadEvent(id, entityName, true, this);
656         Object JavaDoc result = listeners.getLoadEventListener().onLoad(event, LoadEventListener.IMMEDIATE_LOAD);
657
658         ObjectNotFoundException.throwIfNull(result, id, entityName); //should it be UnresolvableObject?
659
return result;
660     }
661
662     public Object JavaDoc internalLoad(String JavaDoc entityName, Serializable JavaDoc id, boolean eager, boolean nullable) throws HibernateException {
663         // todo : remove
664
LoadEventListener.LoadType type = nullable ?
665             LoadEventListener.INTERNAL_LOAD_NULLABLE :
666             eager ? LoadEventListener.INTERNAL_LOAD_EAGER : LoadEventListener.INTERNAL_LOAD_LAZY;
667         LoadEvent event = new LoadEvent(id, entityName, true, this);
668         Object JavaDoc result = listeners.getLoadEventListener().onLoad(event, type);
669         if (!nullable) UnresolvableObjectException.throwIfNull(result, id, entityName);
670         return result;
671     }
672
673     public Object JavaDoc load(Class JavaDoc entityClass, Serializable JavaDoc id, LockMode lockMode) throws HibernateException {
674         return load( entityClass.getName(), id, lockMode );
675     }
676
677     public Object JavaDoc load(String JavaDoc entityName, Serializable JavaDoc id, LockMode lockMode) throws HibernateException {
678         LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
679         return listeners.getLoadEventListener().onLoad(event, LoadEventListener.LOAD);
680     }
681
682     public Object JavaDoc get(Class JavaDoc entityClass, Serializable JavaDoc id, LockMode lockMode) throws HibernateException {
683         return get( entityClass.getName(), id, lockMode );
684     }
685
686     public Object JavaDoc get(String JavaDoc entityName, Serializable JavaDoc id, LockMode lockMode) throws HibernateException {
687         LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
688         return listeners.getLoadEventListener().onLoad(event, LoadEventListener.GET);
689     }
690
691     public void refresh(Object JavaDoc object) throws HibernateException {
692         listeners.getRefreshEventListener().onRefresh( new RefreshEvent(object, this) );
693     }
694
695     public void refresh(Object JavaDoc object, LockMode lockMode) throws HibernateException {
696         listeners.getRefreshEventListener().onRefresh( new RefreshEvent(object, lockMode, this) );
697     }
698
699     public void refresh(Object JavaDoc object, Map JavaDoc refreshedAlready) throws HibernateException {
700         RefreshEvent refreshEvent = new RefreshEvent(object, this);
701         listeners.getRefreshEventListener().onRefresh( refreshEvent, refreshedAlready );
702     }
703
704     public void replicate(Object JavaDoc obj, ReplicationMode replicationMode) throws HibernateException {
705         ReplicateEvent event = new ReplicateEvent(obj, replicationMode, this);
706         listeners.getReplicateEventListener().onReplicate(event);
707     }
708
709     public void replicate(String JavaDoc entityName, Object JavaDoc obj, ReplicationMode replicationMode)
710     throws HibernateException {
711         ReplicateEvent event = new ReplicateEvent(entityName, obj, replicationMode, this);
712         listeners.getReplicateEventListener().onReplicate(event);
713     }
714
715     /**
716      * remove any hard references to the entity that are held by the infrastructure
717      * (references held by application or other persistant instances are okay)
718      */

719     public void evict(Object JavaDoc object) throws HibernateException {
720         listeners.getEvictEventListener().onEvict( new EvictEvent(object, this) );
721     }
722
723     /**
724      * detect in-memory changes, determine if the changes are to tables
725      * named in the query and, if so, complete execution the flush
726      */

727     private boolean autoFlushIfRequired(Set JavaDoc querySpaces) throws HibernateException {
728         AutoFlushEvent event = new AutoFlushEvent(querySpaces, this);
729         return listeners.getAutoFlushEventListener().onAutoFlush(event);
730     }
731
732     public boolean isDirty() throws HibernateException {
733         log.debug("checking session dirtiness");
734         if ( actionQueue.areInsertionsOrDeletionsQueued() ) {
735             log.debug("session dirty (scheduled updates and insertions)");
736             return true;
737         }
738         else {
739             DirtyCheckEvent event = new DirtyCheckEvent(this);
740             return listeners.getDirtyCheckEventListener().onDirtyCheck(event);
741         }
742     }
743
744     public void flush() throws HibernateException {
745         if ( persistenceContext.getCascadeLevel() > 0 ) {
746             throw new HibernateException("Flush during cascade is dangerous");
747         }
748         listeners.getFlushEventListener().onFlush( new FlushEvent(this) );
749     }
750
751     public void forceFlush(EntityEntry e) throws HibernateException {
752         if ( log.isDebugEnabled() ) {
753             log.debug(
754                 "flushing to force deletion of re-saved object: " +
755                 MessageHelper.infoString( e.getPersister(), e.getId(), getFactory() )
756             );
757         }
758
759         if ( persistenceContext.getCascadeLevel() > 0 ) {
760             throw new ObjectDeletedException(
761                 "deleted object would be re-saved by cascade (remove deleted object from associations)",
762                 e.getId(),
763                 e.getPersister().getEntityName()
764             );
765         }
766
767         flush();
768     }
769
770     public Filter enableFilter(String JavaDoc filterName) {
771         FilterImpl filter = new FilterImpl( factory.getFilterDefinition(filterName) );
772         enabledFilters.put(filterName, filter);
773         return filter;
774     }
775
776     public Filter getEnabledFilter(String JavaDoc filterName) {
777         return (Filter) enabledFilters.get(filterName);
778     }
779
780     public void disableFilter(String JavaDoc filterName) {
781         enabledFilters.remove(filterName);
782     }
783
784     public Object JavaDoc getFilterParameterValue(String JavaDoc filterParameterName) {
785         String JavaDoc[] parsed = parseFilterParameterName(filterParameterName);
786         FilterImpl filter = (FilterImpl) enabledFilters.get( parsed[0] );
787         if (filter == null) {
788             throw new IllegalArgumentException JavaDoc("Filter [" + parsed[0] + "] currently not enabled");
789         }
790         return filter.getParameter( parsed[1] );
791     }
792
793     public Type getFilterParameterType(String JavaDoc filterParameterName) {
794         String JavaDoc[] parsed = parseFilterParameterName(filterParameterName);
795         FilterDefinition filterDef = factory.getFilterDefinition( parsed[0] );
796         if (filterDef == null) {
797             throw new IllegalArgumentException JavaDoc("Filter [" + parsed[0] + "] not defined");
798         }
799         Type type = filterDef.getParameterType( parsed[1] );
800         if (type == null) {
801             // this is an internal error of some sort...
802
throw new InternalError JavaDoc("Unable to locate type for filter parameter");
803         }
804         return type;
805     }
806
807     public Map JavaDoc getEnabledFilters() {
808         // First, validate all the enabled filters...
809
//TODO: this implementation has bad performance
810
Iterator JavaDoc itr = enabledFilters.values().iterator();
811         while ( itr.hasNext() ) {
812             final Filter filter = (Filter) itr.next();
813             filter.validate();
814         }
815         return enabledFilters;
816     }
817
818     private String JavaDoc[] parseFilterParameterName(String JavaDoc filterParameterName) {
819         int dot = filterParameterName.indexOf('.');
820         if (dot <= 0) {
821             throw new IllegalArgumentException JavaDoc("Invalid filter-parameter name format"); // TODO: what type?
822
}
823         String JavaDoc filterName = filterParameterName.substring(0, dot);
824         String JavaDoc parameterName = filterParameterName.substring(dot+1);
825         return new String JavaDoc[] {filterName, parameterName};
826     }
827
828
829     /**
830      * Retrieve a list of persistent objects using a hibernate query
831      */

832     public List JavaDoc find(String JavaDoc query) throws HibernateException {
833         return list( query, new QueryParameters() );
834     }
835
836     public List JavaDoc find(String JavaDoc query, Object JavaDoc value, Type type) throws HibernateException {
837         return list( query, new QueryParameters(type, value) );
838     }
839
840     public List JavaDoc find(String JavaDoc query, Object JavaDoc[] values, Type[] types) throws HibernateException {
841         return list( query, new QueryParameters(types, values) );
842     }
843
844     public List JavaDoc list(String JavaDoc query, QueryParameters queryParameters) throws HibernateException {
845
846         if ( log.isTraceEnabled() ) {
847             log.trace( "find: " + query );
848             queryParameters.traceParameters(factory);
849         }
850
851         queryParameters.validateParameters();
852         QueryTranslator[] q = getQueries(query, false);
853
854         List JavaDoc results = CollectionHelper.EMPTY_LIST;
855
856         dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
857

858         //execute the queries and return all result lists as a single list
859
boolean success = false;
860         try {
861             for ( int i = 0; i < q.length; i++ ) {
862                 List JavaDoc currentResults = q[i].list(this, queryParameters);
863                 currentResults.addAll(results);
864                 results = currentResults;
865             }
866             success = true;
867         }
868         finally {
869             dontFlushFromFind--;
870             afterOperation(success);
871         }
872         return results;
873     }
874
875     public int executeUpdate(String JavaDoc query, QueryParameters queryParameters) throws HibernateException {
876
877         if ( log.isTraceEnabled() ) {
878             log.trace( "executeUpdate: " + query );
879             queryParameters.traceParameters(factory);
880         }
881
882         queryParameters.validateParameters();
883         QueryTranslator[] queryTranslators = getQueries(query, false);
884         
885         int result = 0;
886         boolean success = false;
887         try {
888             for (int i=0; i<queryTranslators.length; i++) {
889                 result += queryTranslators[i].executeUpdate( queryParameters, this );
890             }
891             success = true;
892         }
893         finally {
894             afterOperation(success);
895         }
896         return result;
897     }
898
899     private QueryTranslator[] getQueries(String JavaDoc query, boolean scalar) throws HibernateException {
900
901         // take the union of the query spaces (ie. the queried tables)
902
QueryTranslator[] q = factory.getQuery( query, scalar, getEnabledFilters() );
903         return prepareQueries(q);
904
905     }
906
907     private QueryTranslator[] prepareQueries(QueryTranslator[] q) {
908         HashSet JavaDoc qs = new HashSet JavaDoc();
909         for ( int i = 0; i < q.length; i++ ) {
910             qs.addAll( q[i].getQuerySpaces() );
911         }
912
913         autoFlushIfRequired(qs);
914
915         return q;
916     }
917
918     public Iterator JavaDoc iterate(String JavaDoc query) throws HibernateException {
919         return iterate( query, new QueryParameters() );
920     }
921
922     public Iterator JavaDoc iterate(String JavaDoc query, Object JavaDoc value, Type type) throws HibernateException {
923         return iterate( query, new QueryParameters(type, value) );
924     }
925
926     public Iterator JavaDoc iterate(String JavaDoc query, Object JavaDoc[] values, Type[] types) throws HibernateException {
927         return iterate( query, new QueryParameters(types, values) );
928     }
929
930     public Iterator JavaDoc iterate(String JavaDoc query, QueryParameters queryParameters) throws HibernateException {
931
932         if ( log.isTraceEnabled() ) {
933             log.trace( "iterate: " + query );
934             queryParameters.traceParameters(factory);
935         }
936
937         queryParameters.validateParameters();
938         QueryTranslator[] q = getQueries(query, true);
939
940         if ( q.length == 0 ) return EmptyIterator.INSTANCE;
941
942         Iterator JavaDoc result = null;
943         Iterator JavaDoc[] results = null;
944         boolean many = q.length > 1;
945         if (many) results = new Iterator JavaDoc[q.length];
946
947         dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
948

949         try {
950
951             //execute the queries and return all results as a single iterator
952
for ( int i = 0; i < q.length; i++ ) {
953                 result = q[i].iterate(queryParameters, this);
954                 if (many) results[i] = result;
955             }
956
957             return many ? new JoinedIterator(results) : result;
958
959         }
960         finally {
961             dontFlushFromFind--;
962         }
963     }
964
965     public ScrollableResults scroll(String JavaDoc query, QueryParameters queryParameters) throws HibernateException {
966
967         if ( log.isTraceEnabled() ) {
968             log.trace( "scroll: " + query );
969             queryParameters.traceParameters( factory );
970         }
971
972         QueryTranslator[] q = factory.getQuery( query, false, getEnabledFilters() );
973         if ( q.length != 1 ) throw new QueryException( "implicit polymorphism not supported for scroll() queries" );
974         autoFlushIfRequired( q[0].getQuerySpaces() );
975
976         dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
977
try {
978             return q[0].scroll(queryParameters, this);
979         }
980         finally {
981             dontFlushFromFind--;
982         }
983     }
984
985     public int delete(String JavaDoc query) throws HibernateException {
986         return delete( query, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY );
987     }
988
989     public int delete(String JavaDoc query, Object JavaDoc value, Type type) throws HibernateException {
990         return delete( query, new Object JavaDoc[]{value}, new Type[]{type} );
991     }
992
993     public int delete(String JavaDoc query, Object JavaDoc[] values, Type[] types) throws HibernateException {
994         if ( query == null ) {
995             throw new IllegalArgumentException JavaDoc("attempt to perform delete-by-query with null query");
996         }
997
998         if ( log.isTraceEnabled() ) {
999             log.trace( "delete: " + query );
1000            if ( values.length != 0 ) {
1001                log.trace( "parameters: " + StringHelper.toString( values ) );
1002            }
1003        }
1004
1005        List JavaDoc list = find( query, values, types );
1006        int deletionCount = list.size();
1007        for ( int i = 0; i < deletionCount; i++ ) {
1008            delete( list.get( i ) );
1009        }
1010
1011        return deletionCount;
1012    }
1013
1014    public Query createFilter(Object JavaDoc collection, String JavaDoc queryString) {
1015        CollectionFilterImpl filter = new CollectionFilterImpl(queryString, collection, this);
1016        filter.setComment(queryString);
1017        return filter;
1018    }
1019    
1020    public Query createQuery(String JavaDoc queryString) {
1021        QueryImpl query = new QueryImpl(queryString, this);
1022        query.setComment(queryString);
1023        return query;
1024    }
1025
1026
1027    public Object JavaDoc instantiate(String JavaDoc entityName, Serializable JavaDoc id) throws HibernateException {
1028        return instantiate( factory.getEntityPersister(entityName), id );
1029    }
1030
1031    /**
1032     * give the interceptor an opportunity to override the default instantiation
1033     */

1034    public Object JavaDoc instantiate(EntityPersister persister, Serializable JavaDoc id) throws HibernateException {
1035        Object JavaDoc result = interceptor.instantiate( persister.getEntityName(), entityMode, id );
1036        if ( result == null ) result = persister.instantiate( id, entityMode );
1037        return result;
1038    }
1039
1040    public EntityMode getEntityMode() {
1041        return entityMode;
1042    }
1043
1044    public void setFlushMode(FlushMode flushMode) {
1045        if ( log.isTraceEnabled() ) {
1046            log.trace("setting flush mode to: " + flushMode);
1047        }
1048        this.flushMode = flushMode;
1049    }
1050    
1051    public FlushMode getFlushMode() {
1052        return flushMode;
1053    }
1054
1055    public CacheMode getCacheMode() {
1056        return cacheMode;
1057    }
1058    
1059    public void setCacheMode(CacheMode cacheMode) {
1060        if ( log.isTraceEnabled() ) {
1061            log.trace("setting cache mode to: " + cacheMode);
1062        }
1063        this.cacheMode= cacheMode;
1064    }
1065
1066    public Transaction beginTransaction() throws HibernateException {
1067        if ( !isRootSession ) {
1068            log.warn("Transaction started on non-root session");
1069        }
1070        Transaction tx = jdbcContext.beginTransaction();
1071        interceptor.afterTransactionBegin(tx);
1072        return tx;
1073    }
1074
1075    public EntityPersister getEntityPersister(final String JavaDoc entityName, final Object JavaDoc object) {
1076        if (entityName==null) {
1077            return factory.getEntityPersister( guessEntityName(object) );
1078        }
1079        else {
1080            return factory.getEntityPersister( entityName )
1081                    .getSubclassEntityPersister( object, getFactory(), entityMode );
1082        }
1083    }
1084
1085    // not for internal use:
1086
public Serializable JavaDoc getIdentifier(Object JavaDoc object) throws HibernateException {
1087        if ( object instanceof HibernateProxy ) {
1088            LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
1089            if ( li.getSession() != this ) {
1090                throw new TransientObjectException( "The proxy was not associated with this session" );
1091            }
1092            return li.getIdentifier();
1093        }
1094        else {
1095            EntityEntry entry = persistenceContext.getEntry(object);
1096            if ( entry == null ) {
1097                throw new TransientObjectException( "The instance was not associated with this session" );
1098            }
1099            return entry.getId();
1100        }
1101    }
1102
1103    /**
1104     * Get the id value for an object that is actually associated with the session. This
1105     * is a bit stricter than getEntityIdentifierIfNotUnsaved().
1106     */

1107    public Serializable JavaDoc getContextEntityIdentifier(Object JavaDoc object) {
1108        if ( object instanceof HibernateProxy ) {
1109            return getProxyIdentifier(object);
1110        }
1111        else {
1112            EntityEntry entry = persistenceContext.getEntry(object);
1113            return entry != null ? entry.getId() : null;
1114        }
1115    }
1116    
1117    private Serializable JavaDoc getProxyIdentifier(Object JavaDoc proxy) {
1118        return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getIdentifier();
1119    }
1120
1121    public Collection JavaDoc filter(Object JavaDoc collection, String JavaDoc filter) throws HibernateException {
1122        return listFilter( collection, filter, new QueryParameters( new Type[1], new Object JavaDoc[1] ) );
1123    }
1124
1125    public Collection JavaDoc filter(Object JavaDoc collection, String JavaDoc filter, Object JavaDoc value, Type type) throws HibernateException {
1126        return listFilter( collection, filter, new QueryParameters( new Type[]{null, type}, new Object JavaDoc[]{null, value} ) );
1127    }
1128
1129    public Collection JavaDoc filter(Object JavaDoc collection, String JavaDoc filter, Object JavaDoc[] values, Type[] types)
1130    throws HibernateException {
1131        Object JavaDoc[] vals = new Object JavaDoc[values.length + 1];
1132        Type[] typs = new Type[types.length + 1];
1133        System.arraycopy( values, 0, vals, 1, values.length );
1134        System.arraycopy( types, 0, typs, 1, types.length );
1135        return listFilter( collection, filter, new QueryParameters( typs, vals ) );
1136    }
1137
1138    /**
1139     * 1. determine the collection role of the given collection (this may require a flush, if the
1140     * collecion is recorded as unreferenced)
1141     * 2. obtain a compiled filter query
1142     * 3. autoflush if necessary
1143     */

1144    private FilterTranslator getFilterTranslator(
1145            Object JavaDoc collection,
1146            String JavaDoc filter,
1147            QueryParameters parameters,
1148            boolean scalar)
1149    throws HibernateException {
1150
1151        if ( collection == null ) throw new NullPointerException JavaDoc( "null collection passed to filter" );
1152
1153        if ( log.isTraceEnabled() ) {
1154            log.trace( "filter: " + filter );
1155            parameters.traceParameters(factory);
1156        }
1157
1158        CollectionEntry entry = persistenceContext.getCollectionEntryOrNull(collection);
1159        final CollectionPersister roleBeforeFlush = (entry == null) ? null : entry.getLoadedPersister();
1160
1161        FilterTranslator filterTranslator;
1162        if ( roleBeforeFlush == null ) {
1163            // if it was previously unreferenced, we need
1164
// to flush in order to get its state into the
1165
// database to query
1166
flush();
1167            entry = persistenceContext.getCollectionEntryOrNull(collection);
1168            CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
1169            if ( roleAfterFlush == null ) throw new QueryException( "The collection was unreferenced" );
1170            filterTranslator = factory.getFilter( filter, roleAfterFlush.getRole(), scalar, getEnabledFilters() );
1171        }
1172        else {
1173            // otherwise, we only need to flush if there are
1174
// in-memory changes to the queried tables
1175
filterTranslator = factory.getFilter( filter, roleBeforeFlush.getRole(), scalar, getEnabledFilters() );
1176            if ( autoFlushIfRequired( filterTranslator.getQuerySpaces() ) ) {
1177                // might need to run a different filter entirely after the flush
1178
// because the collection role may have changed
1179
entry = persistenceContext.getCollectionEntryOrNull(collection);
1180                CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
1181                if ( roleBeforeFlush != roleAfterFlush ) {
1182                    if ( roleAfterFlush == null ) throw new QueryException( "The collection was dereferenced" );
1183                    filterTranslator = factory.getFilter( filter, roleAfterFlush.getRole(), scalar, getEnabledFilters() );
1184                }
1185            }
1186        }
1187
1188        parameters.getPositionalParameterValues()[0] = entry.getLoadedKey();
1189        parameters.getPositionalParameterTypes()[0] = entry.getLoadedPersister().getKeyType();
1190
1191        return filterTranslator;
1192    }
1193
1194    public List JavaDoc listFilter(Object JavaDoc collection, String JavaDoc filter, QueryParameters queryParameters)
1195    throws HibernateException {
1196
1197        String JavaDoc[] concreteFilters = QuerySplitter.concreteQueries( filter, factory );
1198        FilterTranslator[] filters = new FilterTranslator[concreteFilters.length];
1199
1200        for ( int i = 0; i < concreteFilters.length; i++ ) {
1201            filters[i] = getFilterTranslator( collection, concreteFilters[i], queryParameters, false );
1202        }
1203
1204        dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
1205

1206        List JavaDoc results = CollectionHelper.EMPTY_LIST;
1207        boolean success = false;
1208        try {
1209            for ( int i = 0; i < concreteFilters.length; i++ ) {
1210                List JavaDoc currentResults = filters[i].list( this, queryParameters );
1211                currentResults.addAll(results);
1212                results = currentResults;
1213            }
1214            success = true;
1215        }
1216        finally {
1217            dontFlushFromFind--;
1218            afterOperation(success);
1219        }
1220        return results;
1221
1222    }
1223
1224    public Iterator JavaDoc iterateFilter(Object JavaDoc collection, String JavaDoc filter, QueryParameters queryParameters)
1225    throws HibernateException {
1226
1227        String JavaDoc[] concreteFilters = QuerySplitter.concreteQueries(filter, factory);
1228        FilterTranslator[] filters = new FilterTranslator[concreteFilters.length];
1229
1230        for ( int i=0; i<concreteFilters.length; i++ ) {
1231            filters[i] = getFilterTranslator( collection, concreteFilters[i], queryParameters, true );
1232        }
1233
1234        if ( filters.length == 0 ) return EmptyIterator.INSTANCE;
1235
1236        Iterator JavaDoc result = null;
1237        Iterator JavaDoc[] results = null;
1238        boolean many = filters.length > 1;
1239        if (many) results = new Iterator JavaDoc[filters.length];
1240
1241        //execute the queries and return all results as a single iterator
1242
for ( int i=0; i<filters.length; i++ ) {
1243            result = filters[i].iterate(queryParameters, this);
1244            if (many) results[i] = result;
1245        }
1246
1247        return many ? new JoinedIterator(results) : result;
1248
1249    }
1250
1251    public Criteria createCriteria(Class JavaDoc persistentClass, String JavaDoc alias) {
1252        return new CriteriaImpl( persistentClass.getName(), alias, this );
1253    }
1254
1255    public Criteria createCriteria(String JavaDoc entityName, String JavaDoc alias) {
1256        return new CriteriaImpl(entityName, alias, this);
1257    }
1258
1259    public Criteria createCriteria(Class JavaDoc persistentClass) {
1260        return new CriteriaImpl( persistentClass.getName(), this );
1261    }
1262
1263    public Criteria createCriteria(String JavaDoc entityName) {
1264        return new CriteriaImpl(entityName, this);
1265    }
1266
1267    public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
1268        String JavaDoc entityName = criteria.getEntityOrClassName();
1269        CriteriaLoader loader = new CriteriaLoader(
1270                getOuterJoinLoadable(entityName),
1271                factory,
1272                criteria,
1273                entityName,
1274                getEnabledFilters()
1275        );
1276        autoFlushIfRequired( loader.getQuerySpaces() );
1277        dontFlushFromFind++;
1278        try {
1279            return loader.scroll(this, scrollMode);
1280        }
1281        finally {
1282            dontFlushFromFind--;
1283        }
1284    }
1285
1286    public List JavaDoc list(CriteriaImpl criteria) throws HibernateException {
1287
1288        String JavaDoc[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
1289        int size = implementors.length;
1290
1291        CriteriaLoader[] loaders = new CriteriaLoader[size];
1292        Set JavaDoc spaces = new HashSet JavaDoc();
1293        for( int i=0; i <size; i++ ) {
1294
1295            loaders[i] = new CriteriaLoader(
1296                    getOuterJoinLoadable( implementors[i] ),
1297                    factory,
1298                    criteria,
1299                    implementors[i],
1300                    getEnabledFilters()
1301                );
1302
1303            spaces.addAll( loaders[i].getQuerySpaces() );
1304
1305        }
1306
1307        autoFlushIfRequired(spaces);
1308
1309        List JavaDoc results = Collections.EMPTY_LIST;
1310        dontFlushFromFind++;
1311        boolean success = false;
1312        try {
1313            for( int i=0; i<size; i++ ) {
1314                final List JavaDoc currentResults = loaders[i].list(this);
1315                currentResults.addAll(results);
1316                results = currentResults;
1317            }
1318            success = true;
1319        }
1320        finally {
1321            dontFlushFromFind--;
1322            afterOperation(success);
1323        }
1324
1325        return results;
1326    }
1327
1328    private OuterJoinLoadable getOuterJoinLoadable(String JavaDoc entityName) throws MappingException {
1329        EntityPersister persister = factory.getEntityPersister(entityName);
1330        if ( !(persister instanceof OuterJoinLoadable) ) {
1331            throw new MappingException( "class persister is not OuterJoinLoadable: " + entityName );
1332        }
1333        return ( OuterJoinLoadable ) persister;
1334    }
1335
1336    public boolean contains(Object JavaDoc object) {
1337        if ( object instanceof HibernateProxy ) {
1338            //do not use proxiesByKey, since not all
1339
//proxies that point to this session's
1340
//instances are in that collection!
1341
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
1342            if ( li.isUninitialized() ) {
1343                //if it is an uninitialized proxy, pointing
1344
//with this session, then when it is accessed,
1345
//the underlying instance will be "contained"
1346
return li.getSession()==this;
1347            }
1348            else {
1349                //if it is initialized, see if the underlying
1350
//instance is contained, since we need to
1351
//account for the fact that it might have been
1352
//evicted
1353
object = li.getImplementation();
1354            }
1355        }
1356        return persistenceContext.isEntryFor(object);
1357    }
1358    
1359    public SQLQuery createSQLQuery(String JavaDoc sql) {
1360        SQLQueryImpl query = new SQLQueryImpl(sql, this);
1361        query.setComment("dynamic native SQL query");
1362        return query;
1363    }
1364
1365    public Query createSQLQuery(String JavaDoc sql, String JavaDoc returnAlias, Class JavaDoc returnClass) {
1366        return new SQLQueryImpl(sql, new String JavaDoc[] { returnAlias }, new Class JavaDoc[] { returnClass }, this);
1367    }
1368
1369    public Query createSQLQuery(String JavaDoc sql, String JavaDoc returnAliases[], Class JavaDoc returnClasses[]) {
1370        return new SQLQueryImpl(sql, returnAliases, returnClasses, this);
1371    }
1372
1373    public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)
1374    throws HibernateException {
1375
1376        if ( log.isTraceEnabled() ) {
1377            log.trace( "scroll SQL query: " + customQuery.getSQL() );
1378        }
1379
1380        CustomLoader loader = new CustomLoader( customQuery, getFactory() );
1381
1382        autoFlushIfRequired( loader.getQuerySpaces() );
1383
1384        dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
1385
try {
1386            return loader.scroll(queryParameters, this);
1387        }
1388        finally {
1389            dontFlushFromFind--;
1390        }
1391    }
1392
1393    // basically just an adapted copy of find(CriteriaImpl)
1394
public List JavaDoc listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)
1395    throws HibernateException {
1396
1397        if ( log.isTraceEnabled() ) log.trace( "SQL query: " + customQuery.getSQL() );
1398        
1399        CustomLoader loader = new CustomLoader( customQuery, getFactory() );
1400
1401        autoFlushIfRequired( loader.getQuerySpaces() );
1402
1403        dontFlushFromFind++;
1404        boolean success = false;
1405        try {
1406            List JavaDoc results = loader.list(this, queryParameters);
1407            success = true;
1408            return results;
1409        }
1410        finally {
1411            dontFlushFromFind--;
1412            afterOperation(success);
1413        }
1414    }
1415
1416    public SessionFactory getSessionFactory() {
1417        return factory;
1418    }
1419    
1420    public void initializeCollection(PersistentCollection collection, boolean writing)
1421    throws HibernateException {
1422        listeners.getInitializeCollectionEventListener()
1423            .onInitializeCollection( new InitializeCollectionEvent(collection, this) );
1424    }
1425
1426    public String JavaDoc bestGuessEntityName(Object JavaDoc object) {
1427        if (object instanceof HibernateProxy) {
1428            object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
1429        }
1430        EntityEntry entry = persistenceContext.getEntry(object);
1431        if (entry==null) {
1432            return guessEntityName(object);
1433        }
1434        else {
1435            return entry.getPersister().getEntityName();
1436        }
1437    }
1438    
1439    public String JavaDoc getEntityName(Object JavaDoc object) {
1440        if (object instanceof HibernateProxy) {
1441            if ( !persistenceContext.containsProxy( object ) ) {
1442                throw new TransientObjectException("proxy was not associated with the session");
1443            }
1444            object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
1445        }
1446
1447        EntityEntry entry = persistenceContext.getEntry(object);
1448        if (entry==null) throwTransientObjectException(object);
1449        return entry.getPersister().getEntityName();
1450    }
1451
1452    private void throwTransientObjectException(Object JavaDoc object) throws HibernateException {
1453        throw new TransientObjectException(
1454                "object references an unsaved transient instance - save the transient instance before flushing: " +
1455                guessEntityName(object)
1456            );
1457    }
1458
1459    public String JavaDoc guessEntityName(Object JavaDoc object) throws HibernateException {
1460        String JavaDoc entity = interceptor.getEntityName( object );
1461        if ( entity == null ) {
1462            if ( object instanceof Map JavaDoc ) {
1463                entity = (String JavaDoc) ( (Map JavaDoc) object ).get( DynamicMapInstantiator.KEY );
1464                if ( entity == null ) throw new HibernateException( "could not determine type of dynamic entity" );
1465            }
1466            else if ( object instanceof Element ) {
1467                // TODO : really need to keep a map of nodeName -> entityName, but that would mean nodeName being distinct
1468
entity = ( (Element) object ).getName();
1469            }
1470            else {
1471                entity = object.getClass().getName();
1472            }
1473        }
1474        return entity;
1475    }
1476
1477    public void cancelQuery() throws HibernateException {
1478        getBatcher().cancelLastQuery();
1479    }
1480
1481    public Interceptor getInterceptor() {
1482        return interceptor;
1483    }
1484
1485    public int getDontFlushFromFind() {
1486        return dontFlushFromFind;
1487    }
1488
1489    public String JavaDoc toString() {
1490        StringBuffer JavaDoc buf = new StringBuffer JavaDoc(500)
1491            .append( "SessionImpl(" );
1492        if ( isOpen() ) {
1493            buf.append(persistenceContext)
1494                .append(";")
1495                .append(actionQueue);
1496        }
1497        else {
1498            buf.append("<closed>");
1499        }
1500        return buf.append(')').toString();
1501    }
1502
1503    public SessionEventListenerConfig getListeners() {
1504        return listeners;
1505    }
1506
1507    public ActionQueue getActionQueue() {
1508        return actionQueue;
1509    }
1510    
1511    public PersistenceContext getPersistenceContext() {
1512        return persistenceContext;
1513    }
1514    
1515    public SessionStatistics getStatistics() {
1516        return new SessionStatisticsImpl(this);
1517    }
1518
1519    public boolean isEventSource() {
1520        return true;
1521    }
1522
1523    public void setReadOnly(Object JavaDoc entity, boolean readOnly) {
1524        persistenceContext.setReadOnly(entity, readOnly);
1525    }
1526
1527    public void afterScrollOperation() {
1528        // nothing to do in a stateful session
1529
}
1530}
1531
Popular Tags