0001: //$Id: SessionImpl.java 10689 2006-11-02 18:53:54Z steve.ebersole@jboss.com $
0002: package org.hibernate.impl;
0003:
0004: import java.io.IOException;
0005: import java.io.ObjectInputStream;
0006: import java.io.ObjectOutputStream;
0007: import java.io.Serializable;
0008: import java.sql.Connection;
0009: import java.util.Collection;
0010: import java.util.Collections;
0011: import java.util.HashMap;
0012: import java.util.HashSet;
0013: import java.util.Iterator;
0014: import java.util.List;
0015: import java.util.Map;
0016: import java.util.Set;
0017:
0018: import org.apache.commons.logging.Log;
0019: import org.apache.commons.logging.LogFactory;
0020: import org.dom4j.Element;
0021: import org.hibernate.CacheMode;
0022: import org.hibernate.ConnectionReleaseMode;
0023: import org.hibernate.Criteria;
0024: import org.hibernate.EntityMode;
0025: import org.hibernate.Filter;
0026: import org.hibernate.FlushMode;
0027: import org.hibernate.HibernateException;
0028: import org.hibernate.Interceptor;
0029: import org.hibernate.LockMode;
0030: import org.hibernate.MappingException;
0031: import org.hibernate.ObjectDeletedException;
0032: import org.hibernate.Query;
0033: import org.hibernate.QueryException;
0034: import org.hibernate.ReplicationMode;
0035: import org.hibernate.SQLQuery;
0036: import org.hibernate.ScrollMode;
0037: import org.hibernate.ScrollableResults;
0038: import org.hibernate.Session;
0039: import org.hibernate.SessionException;
0040: import org.hibernate.SessionFactory;
0041: import org.hibernate.Transaction;
0042: import org.hibernate.TransientObjectException;
0043: import org.hibernate.UnresolvableObjectException;
0044: import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
0045: import org.hibernate.collection.PersistentCollection;
0046: import org.hibernate.engine.ActionQueue;
0047: import org.hibernate.engine.CollectionEntry;
0048: import org.hibernate.engine.EntityEntry;
0049: import org.hibernate.engine.EntityKey;
0050: import org.hibernate.engine.FilterDefinition;
0051: import org.hibernate.engine.PersistenceContext;
0052: import org.hibernate.engine.QueryParameters;
0053: import org.hibernate.engine.StatefulPersistenceContext;
0054: import org.hibernate.engine.Status;
0055: import org.hibernate.engine.query.FilterQueryPlan;
0056: import org.hibernate.engine.query.HQLQueryPlan;
0057: import org.hibernate.engine.query.NativeSQLQueryPlan;
0058: import org.hibernate.event.AutoFlushEvent;
0059: import org.hibernate.event.AutoFlushEventListener;
0060: import org.hibernate.event.DeleteEvent;
0061: import org.hibernate.event.DeleteEventListener;
0062: import org.hibernate.event.DirtyCheckEvent;
0063: import org.hibernate.event.DirtyCheckEventListener;
0064: import org.hibernate.event.EventListeners;
0065: import org.hibernate.event.EventSource;
0066: import org.hibernate.event.EvictEvent;
0067: import org.hibernate.event.EvictEventListener;
0068: import org.hibernate.event.FlushEvent;
0069: import org.hibernate.event.FlushEventListener;
0070: import org.hibernate.event.InitializeCollectionEvent;
0071: import org.hibernate.event.InitializeCollectionEventListener;
0072: import org.hibernate.event.LoadEvent;
0073: import org.hibernate.event.LoadEventListener;
0074: import org.hibernate.event.LockEvent;
0075: import org.hibernate.event.LockEventListener;
0076: import org.hibernate.event.MergeEvent;
0077: import org.hibernate.event.MergeEventListener;
0078: import org.hibernate.event.PersistEvent;
0079: import org.hibernate.event.PersistEventListener;
0080: import org.hibernate.event.RefreshEvent;
0081: import org.hibernate.event.RefreshEventListener;
0082: import org.hibernate.event.ReplicateEvent;
0083: import org.hibernate.event.ReplicateEventListener;
0084: import org.hibernate.event.SaveOrUpdateEvent;
0085: import org.hibernate.event.SaveOrUpdateEventListener;
0086: import org.hibernate.event.LoadEventListener.LoadType;
0087: import org.hibernate.jdbc.Batcher;
0088: import org.hibernate.jdbc.JDBCContext;
0089: import org.hibernate.loader.criteria.CriteriaLoader;
0090: import org.hibernate.loader.custom.CustomLoader;
0091: import org.hibernate.loader.custom.CustomQuery;
0092: import org.hibernate.persister.collection.CollectionPersister;
0093: import org.hibernate.persister.entity.EntityPersister;
0094: import org.hibernate.persister.entity.OuterJoinLoadable;
0095: import org.hibernate.pretty.MessageHelper;
0096: import org.hibernate.proxy.HibernateProxy;
0097: import org.hibernate.proxy.LazyInitializer;
0098: import org.hibernate.stat.SessionStatistics;
0099: import org.hibernate.stat.SessionStatisticsImpl;
0100: import org.hibernate.tuple.DynamicMapInstantiator;
0101: import org.hibernate.type.Type;
0102: import org.hibernate.util.ArrayHelper;
0103: import org.hibernate.util.CollectionHelper;
0104: import org.hibernate.util.StringHelper;
0105:
0106: /**
0107: * Concrete implementation of a Session, and also the central, organizing component
0108: * of Hibernate's internal implementation. As such, this class exposes two interfaces;
0109: * Session itself, to the application, and SessionImplementor, to other components
0110: * of Hibernate. This class is not threadsafe.
0111: *
0112: * @author Gavin King
0113: */
0114: public final class SessionImpl extends AbstractSessionImpl implements
0115: EventSource, org.hibernate.classic.Session, JDBCContext.Context {
0116:
0117: // todo : need to find a clean way to handle the "event source" role
0118: // a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
0119: // passing around seperate reto interceptor, factory, actionQueue, and persistentContext is not manageable...
0120:
0121: private static final Log log = LogFactory.getLog(SessionImpl.class);
0122:
0123: private transient EntityMode entityMode = EntityMode.POJO;
0124: private transient boolean autoClear; //for EJB3
0125:
0126: private transient long timestamp;
0127: private transient FlushMode flushMode = FlushMode.AUTO;
0128: private transient CacheMode cacheMode = CacheMode.NORMAL;
0129:
0130: private transient Interceptor interceptor;
0131:
0132: private transient int dontFlushFromFind = 0;
0133:
0134: private transient ActionQueue actionQueue;
0135: private transient StatefulPersistenceContext persistenceContext;
0136: private transient JDBCContext jdbcContext;
0137: private transient EventListeners listeners;
0138:
0139: private transient boolean flushBeforeCompletionEnabled;
0140: private transient boolean autoCloseSessionEnabled;
0141: private transient ConnectionReleaseMode connectionReleaseMode;
0142:
0143: private transient String fetchProfile;
0144:
0145: private transient Map enabledFilters = new HashMap();
0146:
0147: private transient Session rootSession;
0148: private transient Map childSessionsByEntityMode;
0149:
0150: /**
0151: * Constructor used in building "child sessions".
0152: *
0153: * @param parent The parent session
0154: * @param entityMode
0155: */
0156: private SessionImpl(SessionImpl parent, EntityMode entityMode) {
0157: super (parent.factory);
0158: this .rootSession = parent;
0159: this .timestamp = parent.timestamp;
0160: this .jdbcContext = parent.jdbcContext;
0161: this .interceptor = parent.interceptor;
0162: this .listeners = parent.listeners;
0163: this .actionQueue = new ActionQueue(this );
0164: this .entityMode = entityMode;
0165: this .persistenceContext = new StatefulPersistenceContext(this );
0166: this .flushBeforeCompletionEnabled = false;
0167: this .autoCloseSessionEnabled = false;
0168: this .connectionReleaseMode = null;
0169:
0170: if (factory.getStatistics().isStatisticsEnabled()) {
0171: factory.getStatisticsImplementor().openSession();
0172: }
0173:
0174: log.debug("opened session [" + entityMode + "]");
0175: }
0176:
0177: /**
0178: * Constructor used for openSession(...) processing, as well as construction
0179: * of sessions for getCurrentSession().
0180: *
0181: * @param connection The user-supplied connection to use for this session.
0182: * @param factory The factory from which this session was obtained
0183: * @param autoclose NOT USED
0184: * @param timestamp The timestamp for this session
0185: * @param interceptor The interceptor to be applied to this session
0186: * @param entityMode The entity-mode for this session
0187: * @param flushBeforeCompletionEnabled Should we auto flush before completion of transaction
0188: * @param autoCloseSessionEnabled Should we auto close after completion of transaction
0189: * @param connectionReleaseMode The mode by which we should release JDBC connections.
0190: */
0191: SessionImpl(final Connection connection,
0192: final SessionFactoryImpl factory, final boolean autoclose,
0193: final long timestamp, final Interceptor interceptor,
0194: final EntityMode entityMode,
0195: final boolean flushBeforeCompletionEnabled,
0196: final boolean autoCloseSessionEnabled,
0197: final ConnectionReleaseMode connectionReleaseMode) {
0198: super (factory);
0199: this .rootSession = null;
0200: this .timestamp = timestamp;
0201: this .entityMode = entityMode;
0202: this .interceptor = interceptor;
0203: this .listeners = factory.getEventListeners();
0204: this .actionQueue = new ActionQueue(this );
0205: this .persistenceContext = new StatefulPersistenceContext(this );
0206: this .flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
0207: this .autoCloseSessionEnabled = autoCloseSessionEnabled;
0208: this .connectionReleaseMode = connectionReleaseMode;
0209: this .jdbcContext = new JDBCContext(this , connection,
0210: interceptor);
0211:
0212: if (factory.getStatistics().isStatisticsEnabled()) {
0213: factory.getStatisticsImplementor().openSession();
0214: }
0215:
0216: if (log.isDebugEnabled()) {
0217: log.debug("opened session at timestamp: " + timestamp);
0218: }
0219: }
0220:
0221: public Session getSession(EntityMode entityMode) {
0222: if (this .entityMode == entityMode) {
0223: return this ;
0224: }
0225:
0226: if (rootSession != null) {
0227: rootSession.getSession(entityMode);
0228: }
0229:
0230: errorIfClosed();
0231: checkTransactionSynchStatus();
0232:
0233: SessionImpl rtn = null;
0234: if (childSessionsByEntityMode == null) {
0235: childSessionsByEntityMode = new HashMap();
0236: } else {
0237: rtn = (SessionImpl) childSessionsByEntityMode
0238: .get(entityMode);
0239: }
0240:
0241: if (rtn == null) {
0242: rtn = new SessionImpl(this , entityMode);
0243: childSessionsByEntityMode.put(entityMode, rtn);
0244: }
0245:
0246: return rtn;
0247: }
0248:
0249: public void clear() {
0250: errorIfClosed();
0251: checkTransactionSynchStatus();
0252: persistenceContext.clear();
0253: actionQueue.clear();
0254: }
0255:
0256: public Batcher getBatcher() {
0257: errorIfClosed();
0258: checkTransactionSynchStatus();
0259: // TODO : should remove this exposure
0260: // and have all references to the session's batcher use the ConnectionManager.
0261: return jdbcContext.getConnectionManager().getBatcher();
0262: }
0263:
0264: public long getTimestamp() {
0265: checkTransactionSynchStatus();
0266: return timestamp;
0267: }
0268:
0269: public Connection close() throws HibernateException {
0270: log.trace("closing session");
0271: if (isClosed()) {
0272: throw new SessionException("Session was already closed");
0273: }
0274:
0275: if (factory.getStatistics().isStatisticsEnabled()) {
0276: factory.getStatisticsImplementor().closeSession();
0277: }
0278:
0279: try {
0280: try {
0281: if (childSessionsByEntityMode != null) {
0282: Iterator childSessions = childSessionsByEntityMode
0283: .values().iterator();
0284: while (childSessions.hasNext()) {
0285: final SessionImpl child = (SessionImpl) childSessions
0286: .next();
0287: child.close();
0288: }
0289: }
0290: } catch (Throwable t) {
0291: // just ignore
0292: }
0293:
0294: if (rootSession == null) {
0295: return jdbcContext.getConnectionManager().close();
0296: } else {
0297: return null;
0298: }
0299: } finally {
0300: setClosed();
0301: cleanup();
0302: }
0303: }
0304:
0305: public ConnectionReleaseMode getConnectionReleaseMode() {
0306: checkTransactionSynchStatus();
0307: return connectionReleaseMode;
0308: }
0309:
0310: public boolean isAutoCloseSessionEnabled() {
0311: return autoCloseSessionEnabled;
0312: }
0313:
0314: public boolean isOpen() {
0315: checkTransactionSynchStatus();
0316: return !isClosed();
0317: }
0318:
0319: public boolean isFlushModeNever() {
0320: return FlushMode.isManualFlushMode(getFlushMode());
0321: }
0322:
0323: public boolean isFlushBeforeCompletionEnabled() {
0324: return flushBeforeCompletionEnabled;
0325: }
0326:
0327: public void managedFlush() {
0328: if (isClosed()) {
0329: log.trace("skipping auto-flush due to session closed");
0330: return;
0331: }
0332: log.trace("automatically flushing session");
0333: flush();
0334:
0335: if (childSessionsByEntityMode != null) {
0336: Iterator iter = childSessionsByEntityMode.values()
0337: .iterator();
0338: while (iter.hasNext()) {
0339: ((Session) iter.next()).flush();
0340: }
0341: }
0342: }
0343:
0344: public boolean shouldAutoClose() {
0345: return isAutoCloseSessionEnabled() && !isClosed();
0346: }
0347:
0348: public void managedClose() {
0349: log.trace("automatically closing session");
0350: close();
0351: }
0352:
0353: public Connection connection() throws HibernateException {
0354: errorIfClosed();
0355: return jdbcContext.borrowConnection();
0356: }
0357:
0358: public boolean isConnected() {
0359: checkTransactionSynchStatus();
0360: return !isClosed()
0361: && jdbcContext.getConnectionManager()
0362: .isCurrentlyConnected();
0363: }
0364:
0365: public boolean isTransactionInProgress() {
0366: checkTransactionSynchStatus();
0367: return !isClosed() && jdbcContext.isTransactionInProgress();
0368: }
0369:
0370: public Connection disconnect() throws HibernateException {
0371: errorIfClosed();
0372: log.debug("disconnecting session");
0373: return jdbcContext.getConnectionManager().manualDisconnect();
0374: }
0375:
0376: public void reconnect() throws HibernateException {
0377: errorIfClosed();
0378: log.debug("reconnecting session");
0379: checkTransactionSynchStatus();
0380: jdbcContext.getConnectionManager().manualReconnect();
0381: }
0382:
0383: public void reconnect(Connection conn) throws HibernateException {
0384: errorIfClosed();
0385: log.debug("reconnecting session");
0386: checkTransactionSynchStatus();
0387: jdbcContext.getConnectionManager().manualReconnect(conn);
0388: }
0389:
0390: public void beforeTransactionCompletion(Transaction tx) {
0391: log.trace("before transaction completion");
0392: if (rootSession == null) {
0393: try {
0394: interceptor.beforeTransactionCompletion(tx);
0395: } catch (Throwable t) {
0396: log
0397: .error(
0398: "exception in interceptor beforeTransactionCompletion()",
0399: t);
0400: }
0401: }
0402: }
0403:
0404: public void setAutoClear(boolean enabled) {
0405: errorIfClosed();
0406: autoClear = enabled;
0407: }
0408:
0409: /**
0410: * Check if there is a Hibernate or JTA transaction in progress and,
0411: * if there is not, flush if necessary, make sure the connection has
0412: * been committed (if it is not in autocommit mode) and run the after
0413: * completion processing
0414: */
0415: public void afterOperation(boolean success) {
0416: if (!jdbcContext.isTransactionInProgress()) {
0417: jdbcContext.afterNontransactionalQuery(success);
0418: }
0419: }
0420:
0421: public void afterTransactionCompletion(boolean success,
0422: Transaction tx) {
0423: log.trace("after transaction completion");
0424: persistenceContext.afterTransactionCompletion();
0425: actionQueue.afterTransactionCompletion(success);
0426: if (rootSession == null && tx != null) {
0427: try {
0428: interceptor.afterTransactionCompletion(tx);
0429: } catch (Throwable t) {
0430: log
0431: .error(
0432: "exception in interceptor afterTransactionCompletion()",
0433: t);
0434: }
0435: }
0436: if (autoClear) {
0437: clear();
0438: }
0439: }
0440:
0441: /**
0442: * clear all the internal collections, just
0443: * to help the garbage collector, does not
0444: * clear anything that is needed during the
0445: * afterTransactionCompletion() phase
0446: */
0447: private void cleanup() {
0448: persistenceContext.clear();
0449: }
0450:
0451: public LockMode getCurrentLockMode(Object object)
0452: throws HibernateException {
0453: errorIfClosed();
0454: checkTransactionSynchStatus();
0455: if (object == null) {
0456: throw new NullPointerException(
0457: "null object passed to getCurrentLockMode()");
0458: }
0459: if (object instanceof HibernateProxy) {
0460: object = ((HibernateProxy) object)
0461: .getHibernateLazyInitializer().getImplementation(
0462: this );
0463: if (object == null) {
0464: return LockMode.NONE;
0465: }
0466: }
0467: EntityEntry e = persistenceContext.getEntry(object);
0468: if (e == null) {
0469: throw new TransientObjectException(
0470: "Given object not associated with the session");
0471: }
0472: if (e.getStatus() != Status.MANAGED) {
0473: throw new ObjectDeletedException(
0474: "The given object was deleted", e.getId(), e
0475: .getPersister().getEntityName());
0476: }
0477: return e.getLockMode();
0478: }
0479:
0480: public Object getEntityUsingInterceptor(EntityKey key)
0481: throws HibernateException {
0482: errorIfClosed();
0483: // todo : should this get moved to PersistentContext?
0484: // logically, is PersistentContext the "thing" to which an interceptor gets attached?
0485: final Object result = persistenceContext.getEntity(key);
0486: if (result == null) {
0487: final Object newObject = interceptor.getEntity(key
0488: .getEntityName(), key.getIdentifier());
0489: if (newObject != null) {
0490: lock(newObject, LockMode.NONE);
0491: }
0492: return newObject;
0493: } else {
0494: return result;
0495: }
0496: }
0497:
0498: // saveOrUpdate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0499:
0500: public void saveOrUpdate(Object object) throws HibernateException {
0501: saveOrUpdate(null, object);
0502: }
0503:
0504: public void saveOrUpdate(String entityName, Object obj)
0505: throws HibernateException {
0506: fireSaveOrUpdate(new SaveOrUpdateEvent(entityName, obj, this ));
0507: }
0508:
0509: private void fireSaveOrUpdate(SaveOrUpdateEvent event) {
0510: errorIfClosed();
0511: checkTransactionSynchStatus();
0512: SaveOrUpdateEventListener[] saveOrUpdateEventListener = listeners
0513: .getSaveOrUpdateEventListeners();
0514: for (int i = 0; i < saveOrUpdateEventListener.length; i++) {
0515: saveOrUpdateEventListener[i].onSaveOrUpdate(event);
0516: }
0517: }
0518:
0519: // save() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0520:
0521: public void save(Object obj, Serializable id)
0522: throws HibernateException {
0523: save(null, obj, id);
0524: }
0525:
0526: public Serializable save(Object obj) throws HibernateException {
0527: return save(null, obj);
0528: }
0529:
0530: public Serializable save(String entityName, Object object)
0531: throws HibernateException {
0532: return fireSave(new SaveOrUpdateEvent(entityName, object, this ));
0533: }
0534:
0535: public void save(String entityName, Object object, Serializable id)
0536: throws HibernateException {
0537: fireSave(new SaveOrUpdateEvent(entityName, object, id, this ));
0538: }
0539:
0540: private Serializable fireSave(SaveOrUpdateEvent event) {
0541: errorIfClosed();
0542: checkTransactionSynchStatus();
0543: SaveOrUpdateEventListener[] saveEventListener = listeners
0544: .getSaveEventListeners();
0545: for (int i = 0; i < saveEventListener.length; i++) {
0546: saveEventListener[i].onSaveOrUpdate(event);
0547: }
0548: return event.getResultId();
0549: }
0550:
0551: // update() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0552:
0553: public void update(Object obj) throws HibernateException {
0554: update(null, obj);
0555: }
0556:
0557: public void update(Object obj, Serializable id)
0558: throws HibernateException {
0559: update(null, obj, id);
0560: }
0561:
0562: public void update(String entityName, Object object)
0563: throws HibernateException {
0564: fireUpdate(new SaveOrUpdateEvent(entityName, object, this ));
0565: }
0566:
0567: public void update(String entityName, Object object, Serializable id)
0568: throws HibernateException {
0569: fireUpdate(new SaveOrUpdateEvent(entityName, object, id, this ));
0570: }
0571:
0572: private void fireUpdate(SaveOrUpdateEvent event) {
0573: errorIfClosed();
0574: checkTransactionSynchStatus();
0575: SaveOrUpdateEventListener[] updateEventListener = listeners
0576: .getUpdateEventListeners();
0577: for (int i = 0; i < updateEventListener.length; i++) {
0578: updateEventListener[i].onSaveOrUpdate(event);
0579: }
0580: }
0581:
0582: // lock() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0583:
0584: public void lock(String entityName, Object object, LockMode lockMode)
0585: throws HibernateException {
0586: fireLock(new LockEvent(entityName, object, lockMode, this ));
0587: }
0588:
0589: public void lock(Object object, LockMode lockMode)
0590: throws HibernateException {
0591: fireLock(new LockEvent(object, lockMode, this ));
0592: }
0593:
0594: private void fireLock(LockEvent lockEvent) {
0595: errorIfClosed();
0596: checkTransactionSynchStatus();
0597: LockEventListener[] lockEventListener = listeners
0598: .getLockEventListeners();
0599: for (int i = 0; i < lockEventListener.length; i++) {
0600: lockEventListener[i].onLock(lockEvent);
0601: }
0602: }
0603:
0604: // persist() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0605:
0606: public void persist(String entityName, Object object)
0607: throws HibernateException {
0608: firePersist(new PersistEvent(entityName, object, this ));
0609: }
0610:
0611: public void persist(Object object) throws HibernateException {
0612: persist(null, object);
0613: }
0614:
0615: public void persist(String entityName, Object object,
0616: Map copiedAlready) throws HibernateException {
0617: firePersist(copiedAlready, new PersistEvent(entityName, object,
0618: this ));
0619: }
0620:
0621: private void firePersist(Map copiedAlready, PersistEvent event) {
0622: errorIfClosed();
0623: checkTransactionSynchStatus();
0624: PersistEventListener[] persistEventListener = listeners
0625: .getPersistEventListeners();
0626: for (int i = 0; i < persistEventListener.length; i++) {
0627: persistEventListener[i].onPersist(event, copiedAlready);
0628: }
0629: }
0630:
0631: private void firePersist(PersistEvent event) {
0632: errorIfClosed();
0633: checkTransactionSynchStatus();
0634: PersistEventListener[] createEventListener = listeners
0635: .getPersistEventListeners();
0636: for (int i = 0; i < createEventListener.length; i++) {
0637: createEventListener[i].onPersist(event);
0638: }
0639: }
0640:
0641: // persistOnFlush() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0642:
0643: public void persistOnFlush(String entityName, Object object)
0644: throws HibernateException {
0645: firePersistOnFlush(new PersistEvent(entityName, object, this ));
0646: }
0647:
0648: public void persistOnFlush(Object object) throws HibernateException {
0649: persist(null, object);
0650: }
0651:
0652: public void persistOnFlush(String entityName, Object object,
0653: Map copiedAlready) throws HibernateException {
0654: firePersistOnFlush(copiedAlready, new PersistEvent(entityName,
0655: object, this ));
0656: }
0657:
0658: private void firePersistOnFlush(Map copiedAlready,
0659: PersistEvent event) {
0660: errorIfClosed();
0661: checkTransactionSynchStatus();
0662: PersistEventListener[] persistEventListener = listeners
0663: .getPersistOnFlushEventListeners();
0664: for (int i = 0; i < persistEventListener.length; i++) {
0665: persistEventListener[i].onPersist(event, copiedAlready);
0666: }
0667: }
0668:
0669: private void firePersistOnFlush(PersistEvent event) {
0670: errorIfClosed();
0671: checkTransactionSynchStatus();
0672: PersistEventListener[] createEventListener = listeners
0673: .getPersistOnFlushEventListeners();
0674: for (int i = 0; i < createEventListener.length; i++) {
0675: createEventListener[i].onPersist(event);
0676: }
0677: }
0678:
0679: // merge() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0680:
0681: public Object merge(String entityName, Object object)
0682: throws HibernateException {
0683: return fireMerge(new MergeEvent(entityName, object, this ));
0684: }
0685:
0686: public Object merge(Object object) throws HibernateException {
0687: return merge(null, object);
0688: }
0689:
0690: public void merge(String entityName, Object object,
0691: Map copiedAlready) throws HibernateException {
0692: fireMerge(copiedAlready, new MergeEvent(entityName, object,
0693: this ));
0694: }
0695:
0696: private Object fireMerge(MergeEvent event) {
0697: errorIfClosed();
0698: checkTransactionSynchStatus();
0699: MergeEventListener[] mergeEventListener = listeners
0700: .getMergeEventListeners();
0701: for (int i = 0; i < mergeEventListener.length; i++) {
0702: mergeEventListener[i].onMerge(event);
0703: }
0704: return event.getResult();
0705: }
0706:
0707: private void fireMerge(Map copiedAlready, MergeEvent event) {
0708: errorIfClosed();
0709: checkTransactionSynchStatus();
0710: MergeEventListener[] mergeEventListener = listeners
0711: .getMergeEventListeners();
0712: for (int i = 0; i < mergeEventListener.length; i++) {
0713: mergeEventListener[i].onMerge(event, copiedAlready);
0714: }
0715: }
0716:
0717: // saveOrUpdateCopy() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0718:
0719: public Object saveOrUpdateCopy(String entityName, Object object)
0720: throws HibernateException {
0721: return fireSaveOrUpdateCopy(new MergeEvent(entityName, object,
0722: this ));
0723: }
0724:
0725: public Object saveOrUpdateCopy(Object object)
0726: throws HibernateException {
0727: return saveOrUpdateCopy(null, object);
0728: }
0729:
0730: public Object saveOrUpdateCopy(String entityName, Object object,
0731: Serializable id) throws HibernateException {
0732: return fireSaveOrUpdateCopy(new MergeEvent(entityName, object,
0733: id, this ));
0734: }
0735:
0736: public Object saveOrUpdateCopy(Object object, Serializable id)
0737: throws HibernateException {
0738: return saveOrUpdateCopy(null, object, id);
0739: }
0740:
0741: public void saveOrUpdateCopy(String entityName, Object object,
0742: Map copiedAlready) throws HibernateException {
0743: fireSaveOrUpdateCopy(copiedAlready, new MergeEvent(entityName,
0744: object, this ));
0745: }
0746:
0747: private void fireSaveOrUpdateCopy(Map copiedAlready,
0748: MergeEvent event) {
0749: errorIfClosed();
0750: checkTransactionSynchStatus();
0751: MergeEventListener[] saveOrUpdateCopyEventListener = listeners
0752: .getSaveOrUpdateCopyEventListeners();
0753: for (int i = 0; i < saveOrUpdateCopyEventListener.length; i++) {
0754: saveOrUpdateCopyEventListener[i].onMerge(event,
0755: copiedAlready);
0756: }
0757: }
0758:
0759: private Object fireSaveOrUpdateCopy(MergeEvent event) {
0760: errorIfClosed();
0761: checkTransactionSynchStatus();
0762: MergeEventListener[] saveOrUpdateCopyEventListener = listeners
0763: .getSaveOrUpdateCopyEventListeners();
0764: for (int i = 0; i < saveOrUpdateCopyEventListener.length; i++) {
0765: saveOrUpdateCopyEventListener[i].onMerge(event);
0766: }
0767: return event.getResult();
0768: }
0769:
0770: // delete() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0771:
0772: /**
0773: * Delete a persistent object
0774: */
0775: public void delete(Object object) throws HibernateException {
0776: fireDelete(new DeleteEvent(object, this ));
0777: }
0778:
0779: /**
0780: * Delete a persistent object (by explicit entity name)
0781: */
0782: public void delete(String entityName, Object object)
0783: throws HibernateException {
0784: fireDelete(new DeleteEvent(entityName, object, this ));
0785: }
0786:
0787: /**
0788: * Delete a persistent object
0789: */
0790: public void delete(String entityName, Object object,
0791: boolean isCascadeDeleteEnabled, Set transientEntities)
0792: throws HibernateException {
0793: fireDelete(new DeleteEvent(entityName, object,
0794: isCascadeDeleteEnabled, this ), transientEntities);
0795: }
0796:
0797: private void fireDelete(DeleteEvent event) {
0798: errorIfClosed();
0799: checkTransactionSynchStatus();
0800: DeleteEventListener[] deleteEventListener = listeners
0801: .getDeleteEventListeners();
0802: for (int i = 0; i < deleteEventListener.length; i++) {
0803: deleteEventListener[i].onDelete(event);
0804: }
0805: }
0806:
0807: private void fireDelete(DeleteEvent event, Set transientEntities) {
0808: errorIfClosed();
0809: checkTransactionSynchStatus();
0810: DeleteEventListener[] deleteEventListener = listeners
0811: .getDeleteEventListeners();
0812: for (int i = 0; i < deleteEventListener.length; i++) {
0813: deleteEventListener[i].onDelete(event, transientEntities);
0814: }
0815: }
0816:
0817: // load()/get() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0818:
0819: public void load(Object object, Serializable id)
0820: throws HibernateException {
0821: LoadEvent event = new LoadEvent(id, object, this );
0822: fireLoad(event, LoadEventListener.RELOAD);
0823: }
0824:
0825: public Object load(Class entityClass, Serializable id)
0826: throws HibernateException {
0827: return load(entityClass.getName(), id);
0828: }
0829:
0830: public Object load(String entityName, Serializable id)
0831: throws HibernateException {
0832: LoadEvent event = new LoadEvent(id, entityName, false, this );
0833: boolean success = false;
0834: try {
0835: fireLoad(event, LoadEventListener.LOAD);
0836: if (event.getResult() == null) {
0837: getFactory().getEntityNotFoundDelegate()
0838: .handleEntityNotFound(entityName, id);
0839: }
0840: success = true;
0841: return event.getResult();
0842: } finally {
0843: afterOperation(success);
0844: }
0845: }
0846:
0847: public Object get(Class entityClass, Serializable id)
0848: throws HibernateException {
0849: return get(entityClass.getName(), id);
0850: }
0851:
0852: public Object get(String entityName, Serializable id)
0853: throws HibernateException {
0854: LoadEvent event = new LoadEvent(id, entityName, false, this );
0855: boolean success = false;
0856: try {
0857: fireLoad(event, LoadEventListener.GET);
0858: success = true;
0859: return event.getResult();
0860: } finally {
0861: afterOperation(success);
0862: }
0863: }
0864:
0865: /**
0866: * Load the data for the object with the specified id into a newly created object.
0867: * This is only called when lazily initializing a proxy.
0868: * Do NOT return a proxy.
0869: */
0870: public Object immediateLoad(String entityName, Serializable id)
0871: throws HibernateException {
0872: if (log.isDebugEnabled()) {
0873: EntityPersister persister = getFactory()
0874: .getEntityPersister(entityName);
0875: log.debug("initializing proxy: "
0876: + MessageHelper.infoString(persister, id,
0877: getFactory()));
0878: }
0879:
0880: LoadEvent event = new LoadEvent(id, entityName, true, this );
0881: fireLoad(event, LoadEventListener.IMMEDIATE_LOAD);
0882: return event.getResult();
0883: }
0884:
0885: public Object internalLoad(String entityName, Serializable id,
0886: boolean eager, boolean nullable) throws HibernateException {
0887: // todo : remove
0888: LoadEventListener.LoadType type = nullable ? LoadEventListener.INTERNAL_LOAD_NULLABLE
0889: : eager ? LoadEventListener.INTERNAL_LOAD_EAGER
0890: : LoadEventListener.INTERNAL_LOAD_LAZY;
0891: LoadEvent event = new LoadEvent(id, entityName, true, this );
0892: fireLoad(event, type);
0893: if (!nullable) {
0894: UnresolvableObjectException.throwIfNull(event.getResult(),
0895: id, entityName);
0896: }
0897: return event.getResult();
0898: }
0899:
0900: public Object load(Class entityClass, Serializable id,
0901: LockMode lockMode) throws HibernateException {
0902: return load(entityClass.getName(), id, lockMode);
0903: }
0904:
0905: public Object load(String entityName, Serializable id,
0906: LockMode lockMode) throws HibernateException {
0907: LoadEvent event = new LoadEvent(id, entityName, lockMode, this );
0908: fireLoad(event, LoadEventListener.LOAD);
0909: return event.getResult();
0910: }
0911:
0912: public Object get(Class entityClass, Serializable id,
0913: LockMode lockMode) throws HibernateException {
0914: return get(entityClass.getName(), id, lockMode);
0915: }
0916:
0917: public Object get(String entityName, Serializable id,
0918: LockMode lockMode) throws HibernateException {
0919: LoadEvent event = new LoadEvent(id, entityName, lockMode, this );
0920: fireLoad(event, LoadEventListener.GET);
0921: return event.getResult();
0922: }
0923:
0924: private void fireLoad(LoadEvent event, LoadType loadType) {
0925: errorIfClosed();
0926: checkTransactionSynchStatus();
0927: LoadEventListener[] loadEventListener = listeners
0928: .getLoadEventListeners();
0929: for (int i = 0; i < loadEventListener.length; i++) {
0930: loadEventListener[i].onLoad(event, loadType);
0931: }
0932: }
0933:
0934: // refresh() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0935:
0936: public void refresh(Object object) throws HibernateException {
0937: fireRefresh(new RefreshEvent(object, this ));
0938: }
0939:
0940: public void refresh(Object object, LockMode lockMode)
0941: throws HibernateException {
0942: fireRefresh(new RefreshEvent(object, lockMode, this ));
0943: }
0944:
0945: public void refresh(Object object, Map refreshedAlready)
0946: throws HibernateException {
0947: fireRefresh(refreshedAlready, new RefreshEvent(object, this ));
0948: }
0949:
0950: private void fireRefresh(RefreshEvent refreshEvent) {
0951: errorIfClosed();
0952: checkTransactionSynchStatus();
0953: RefreshEventListener[] refreshEventListener = listeners
0954: .getRefreshEventListeners();
0955: for (int i = 0; i < refreshEventListener.length; i++) {
0956: refreshEventListener[i].onRefresh(refreshEvent);
0957: }
0958: }
0959:
0960: private void fireRefresh(Map refreshedAlready,
0961: RefreshEvent refreshEvent) {
0962: errorIfClosed();
0963: checkTransactionSynchStatus();
0964: RefreshEventListener[] refreshEventListener = listeners
0965: .getRefreshEventListeners();
0966: for (int i = 0; i < refreshEventListener.length; i++) {
0967: refreshEventListener[i].onRefresh(refreshEvent,
0968: refreshedAlready);
0969: }
0970: }
0971:
0972: // replicate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0973:
0974: public void replicate(Object obj, ReplicationMode replicationMode)
0975: throws HibernateException {
0976: fireReplicate(new ReplicateEvent(obj, replicationMode, this ));
0977: }
0978:
0979: public void replicate(String entityName, Object obj,
0980: ReplicationMode replicationMode) throws HibernateException {
0981: fireReplicate(new ReplicateEvent(entityName, obj,
0982: replicationMode, this ));
0983: }
0984:
0985: private void fireReplicate(ReplicateEvent event) {
0986: errorIfClosed();
0987: checkTransactionSynchStatus();
0988: ReplicateEventListener[] replicateEventListener = listeners
0989: .getReplicateEventListeners();
0990: for (int i = 0; i < replicateEventListener.length; i++) {
0991: replicateEventListener[i].onReplicate(event);
0992: }
0993: }
0994:
0995: // evict() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0996:
0997: /**
0998: * remove any hard references to the entity that are held by the infrastructure
0999: * (references held by application or other persistant instances are okay)
1000: */
1001: public void evict(Object object) throws HibernateException {
1002: fireEvict(new EvictEvent(object, this ));
1003: }
1004:
1005: private void fireEvict(EvictEvent evictEvent) {
1006: errorIfClosed();
1007: checkTransactionSynchStatus();
1008: EvictEventListener[] evictEventListener = listeners
1009: .getEvictEventListeners();
1010: for (int i = 0; i < evictEventListener.length; i++) {
1011: evictEventListener[i].onEvict(evictEvent);
1012: }
1013: }
1014:
1015: /**
1016: * detect in-memory changes, determine if the changes are to tables
1017: * named in the query and, if so, complete execution the flush
1018: */
1019: protected boolean autoFlushIfRequired(Set querySpaces)
1020: throws HibernateException {
1021: errorIfClosed();
1022: if (!isTransactionInProgress()) {
1023: // do not auto-flush while outside a transaction
1024: return false;
1025: }
1026: AutoFlushEvent event = new AutoFlushEvent(querySpaces, this );
1027: AutoFlushEventListener[] autoFlushEventListener = listeners
1028: .getAutoFlushEventListeners();
1029: for (int i = 0; i < autoFlushEventListener.length; i++) {
1030: autoFlushEventListener[i].onAutoFlush(event);
1031: }
1032: return event.isFlushRequired();
1033: }
1034:
1035: public boolean isDirty() throws HibernateException {
1036: errorIfClosed();
1037: checkTransactionSynchStatus();
1038: log.debug("checking session dirtiness");
1039: if (actionQueue.areInsertionsOrDeletionsQueued()) {
1040: log
1041: .debug("session dirty (scheduled updates and insertions)");
1042: return true;
1043: } else {
1044: DirtyCheckEvent event = new DirtyCheckEvent(this );
1045: DirtyCheckEventListener[] dirtyCheckEventListener = listeners
1046: .getDirtyCheckEventListeners();
1047: for (int i = 0; i < dirtyCheckEventListener.length; i++) {
1048: dirtyCheckEventListener[i].onDirtyCheck(event);
1049: }
1050: return event.isDirty();
1051: }
1052: }
1053:
1054: public void flush() throws HibernateException {
1055: errorIfClosed();
1056: checkTransactionSynchStatus();
1057: if (persistenceContext.getCascadeLevel() > 0) {
1058: throw new HibernateException(
1059: "Flush during cascade is dangerous");
1060: }
1061: FlushEventListener[] flushEventListener = listeners
1062: .getFlushEventListeners();
1063: for (int i = 0; i < flushEventListener.length; i++) {
1064: flushEventListener[i].onFlush(new FlushEvent(this ));
1065: }
1066: }
1067:
1068: public void forceFlush(EntityEntry entityEntry)
1069: throws HibernateException {
1070: errorIfClosed();
1071: if (log.isDebugEnabled()) {
1072: log.debug("flushing to force deletion of re-saved object: "
1073: + MessageHelper.infoString(entityEntry
1074: .getPersister(), entityEntry.getId(),
1075: getFactory()));
1076: }
1077:
1078: if (persistenceContext.getCascadeLevel() > 0) {
1079: throw new ObjectDeletedException(
1080: "deleted object would be re-saved by cascade (remove deleted object from associations)",
1081: entityEntry.getId(), entityEntry.getPersister()
1082: .getEntityName());
1083: }
1084:
1085: flush();
1086: }
1087:
1088: public Filter getEnabledFilter(String filterName) {
1089: checkTransactionSynchStatus();
1090: return (Filter) enabledFilters.get(filterName);
1091: }
1092:
1093: public Filter enableFilter(String filterName) {
1094: errorIfClosed();
1095: checkTransactionSynchStatus();
1096: FilterImpl filter = new FilterImpl(factory
1097: .getFilterDefinition(filterName));
1098: enabledFilters.put(filterName, filter);
1099: return filter;
1100: }
1101:
1102: public void disableFilter(String filterName) {
1103: errorIfClosed();
1104: checkTransactionSynchStatus();
1105: enabledFilters.remove(filterName);
1106: }
1107:
1108: public Object getFilterParameterValue(String filterParameterName) {
1109: errorIfClosed();
1110: checkTransactionSynchStatus();
1111: String[] parsed = parseFilterParameterName(filterParameterName);
1112: FilterImpl filter = (FilterImpl) enabledFilters.get(parsed[0]);
1113: if (filter == null) {
1114: throw new IllegalArgumentException("Filter [" + parsed[0]
1115: + "] currently not enabled");
1116: }
1117: return filter.getParameter(parsed[1]);
1118: }
1119:
1120: public Type getFilterParameterType(String filterParameterName) {
1121: errorIfClosed();
1122: checkTransactionSynchStatus();
1123: String[] parsed = parseFilterParameterName(filterParameterName);
1124: FilterDefinition filterDef = factory
1125: .getFilterDefinition(parsed[0]);
1126: if (filterDef == null) {
1127: throw new IllegalArgumentException("Filter [" + parsed[0]
1128: + "] not defined");
1129: }
1130: Type type = filterDef.getParameterType(parsed[1]);
1131: if (type == null) {
1132: // this is an internal error of some sort...
1133: throw new InternalError(
1134: "Unable to locate type for filter parameter");
1135: }
1136: return type;
1137: }
1138:
1139: public Map getEnabledFilters() {
1140: errorIfClosed();
1141: checkTransactionSynchStatus();
1142: // First, validate all the enabled filters...
1143: //TODO: this implementation has bad performance
1144: Iterator itr = enabledFilters.values().iterator();
1145: while (itr.hasNext()) {
1146: final Filter filter = (Filter) itr.next();
1147: filter.validate();
1148: }
1149: return enabledFilters;
1150: }
1151:
1152: private String[] parseFilterParameterName(String filterParameterName) {
1153: int dot = filterParameterName.indexOf('.');
1154: if (dot <= 0) {
1155: throw new IllegalArgumentException(
1156: "Invalid filter-parameter name format"); // TODO: what type?
1157: }
1158: String filterName = filterParameterName.substring(0, dot);
1159: String parameterName = filterParameterName.substring(dot + 1);
1160: return new String[] { filterName, parameterName };
1161: }
1162:
1163: /**
1164: * Retrieve a list of persistent objects using a hibernate query
1165: */
1166: public List find(String query) throws HibernateException {
1167: return list(query, new QueryParameters());
1168: }
1169:
1170: public List find(String query, Object value, Type type)
1171: throws HibernateException {
1172: return list(query, new QueryParameters(type, value));
1173: }
1174:
1175: public List find(String query, Object[] values, Type[] types)
1176: throws HibernateException {
1177: return list(query, new QueryParameters(types, values));
1178: }
1179:
1180: public List list(String query, QueryParameters queryParameters)
1181: throws HibernateException {
1182: errorIfClosed();
1183: checkTransactionSynchStatus();
1184: queryParameters.validateParameters();
1185: HQLQueryPlan plan = getHQLQueryPlan(query, false);
1186: autoFlushIfRequired(plan.getQuerySpaces());
1187:
1188: List results = CollectionHelper.EMPTY_LIST;
1189: boolean success = false;
1190:
1191: dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
1192: try {
1193: results = plan.performList(queryParameters, this );
1194: success = true;
1195: } finally {
1196: dontFlushFromFind--;
1197: afterOperation(success);
1198: }
1199: return results;
1200: }
1201:
1202: public int executeUpdate(String query,
1203: QueryParameters queryParameters) throws HibernateException {
1204: errorIfClosed();
1205: checkTransactionSynchStatus();
1206: queryParameters.validateParameters();
1207: HQLQueryPlan plan = getHQLQueryPlan(query, false);
1208: autoFlushIfRequired(plan.getQuerySpaces());
1209:
1210: boolean success = false;
1211: int result = 0;
1212: try {
1213: result = plan.performExecuteUpdate(queryParameters, this );
1214: success = true;
1215: } finally {
1216: afterOperation(success);
1217: }
1218: return result;
1219: }
1220:
1221: public int executeNativeUpdate(
1222: NativeSQLQuerySpecification nativeQuerySpecification,
1223: QueryParameters queryParameters) throws HibernateException {
1224: errorIfClosed();
1225: checkTransactionSynchStatus();
1226: queryParameters.validateParameters();
1227: NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeQuerySpecification);
1228:
1229: autoFlushIfRequired(plan.getCustomQuery().getQuerySpaces());
1230:
1231: boolean success = false;
1232: int result = 0;
1233: try {
1234: result = plan.performExecuteUpdate(queryParameters, this );
1235: success = true;
1236: } finally {
1237: afterOperation(success);
1238: }
1239: return result;
1240: }
1241:
1242: public Iterator iterate(String query) throws HibernateException {
1243: return iterate(query, new QueryParameters());
1244: }
1245:
1246: public Iterator iterate(String query, Object value, Type type)
1247: throws HibernateException {
1248: return iterate(query, new QueryParameters(type, value));
1249: }
1250:
1251: public Iterator iterate(String query, Object[] values, Type[] types)
1252: throws HibernateException {
1253: return iterate(query, new QueryParameters(types, values));
1254: }
1255:
1256: public Iterator iterate(String query,
1257: QueryParameters queryParameters) throws HibernateException {
1258: errorIfClosed();
1259: checkTransactionSynchStatus();
1260: queryParameters.validateParameters();
1261: HQLQueryPlan plan = getHQLQueryPlan(query, true);
1262: autoFlushIfRequired(plan.getQuerySpaces());
1263:
1264: dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
1265: try {
1266: return plan.performIterate(queryParameters, this );
1267: } finally {
1268: dontFlushFromFind--;
1269: }
1270: }
1271:
1272: public ScrollableResults scroll(String query,
1273: QueryParameters queryParameters) throws HibernateException {
1274: errorIfClosed();
1275: checkTransactionSynchStatus();
1276: HQLQueryPlan plan = getHQLQueryPlan(query, false);
1277: autoFlushIfRequired(plan.getQuerySpaces());
1278: dontFlushFromFind++;
1279: try {
1280: return plan.performScroll(queryParameters, this );
1281: } finally {
1282: dontFlushFromFind--;
1283: }
1284: }
1285:
1286: public int delete(String query) throws HibernateException {
1287: return delete(query, ArrayHelper.EMPTY_OBJECT_ARRAY,
1288: ArrayHelper.EMPTY_TYPE_ARRAY);
1289: }
1290:
1291: public int delete(String query, Object value, Type type)
1292: throws HibernateException {
1293: return delete(query, new Object[] { value },
1294: new Type[] { type });
1295: }
1296:
1297: public int delete(String query, Object[] values, Type[] types)
1298: throws HibernateException {
1299: errorIfClosed();
1300: checkTransactionSynchStatus();
1301: if (query == null) {
1302: throw new IllegalArgumentException(
1303: "attempt to perform delete-by-query with null query");
1304: }
1305:
1306: if (log.isTraceEnabled()) {
1307: log.trace("delete: " + query);
1308: if (values.length != 0) {
1309: log.trace("parameters: "
1310: + StringHelper.toString(values));
1311: }
1312: }
1313:
1314: List list = find(query, values, types);
1315: int deletionCount = list.size();
1316: for (int i = 0; i < deletionCount; i++) {
1317: delete(list.get(i));
1318: }
1319:
1320: return deletionCount;
1321: }
1322:
1323: public Query createFilter(Object collection, String queryString) {
1324: errorIfClosed();
1325: checkTransactionSynchStatus();
1326: CollectionFilterImpl filter = new CollectionFilterImpl(
1327: queryString, collection, this , getFilterQueryPlan(
1328: collection, queryString, null, false)
1329: .getParameterMetadata());
1330: filter.setComment(queryString);
1331: return filter;
1332: }
1333:
1334: public Query getNamedQuery(String queryName)
1335: throws MappingException {
1336: errorIfClosed();
1337: checkTransactionSynchStatus();
1338: return super .getNamedQuery(queryName);
1339: }
1340:
1341: public Object instantiate(String entityName, Serializable id)
1342: throws HibernateException {
1343: return instantiate(factory.getEntityPersister(entityName), id);
1344: }
1345:
1346: /**
1347: * give the interceptor an opportunity to override the default instantiation
1348: */
1349: public Object instantiate(EntityPersister persister, Serializable id)
1350: throws HibernateException {
1351: errorIfClosed();
1352: checkTransactionSynchStatus();
1353: Object result = interceptor.instantiate(persister
1354: .getEntityName(), entityMode, id);
1355: if (result == null) {
1356: result = persister.instantiate(id, entityMode);
1357: }
1358: return result;
1359: }
1360:
1361: public EntityMode getEntityMode() {
1362: checkTransactionSynchStatus();
1363: return entityMode;
1364: }
1365:
1366: public void setFlushMode(FlushMode flushMode) {
1367: errorIfClosed();
1368: checkTransactionSynchStatus();
1369: if (log.isTraceEnabled()) {
1370: log.trace("setting flush mode to: " + flushMode);
1371: }
1372: this .flushMode = flushMode;
1373: }
1374:
1375: public FlushMode getFlushMode() {
1376: checkTransactionSynchStatus();
1377: return flushMode;
1378: }
1379:
1380: public CacheMode getCacheMode() {
1381: checkTransactionSynchStatus();
1382: return cacheMode;
1383: }
1384:
1385: public void setCacheMode(CacheMode cacheMode) {
1386: errorIfClosed();
1387: checkTransactionSynchStatus();
1388: if (log.isTraceEnabled()) {
1389: log.trace("setting cache mode to: " + cacheMode);
1390: }
1391: this .cacheMode = cacheMode;
1392: }
1393:
1394: public Transaction getTransaction() throws HibernateException {
1395: errorIfClosed();
1396: return jdbcContext.getTransaction();
1397: }
1398:
1399: public Transaction beginTransaction() throws HibernateException {
1400: errorIfClosed();
1401: if (rootSession != null) {
1402: // todo : should seriously consider not allowing a txn to begin from a child session
1403: // can always route the request to the root session...
1404: log.warn("Transaction started on non-root session");
1405: }
1406: Transaction result = getTransaction();
1407: result.begin();
1408: return result;
1409: }
1410:
1411: public void afterTransactionBegin(Transaction tx) {
1412: errorIfClosed();
1413: interceptor.afterTransactionBegin(tx);
1414: }
1415:
1416: public EntityPersister getEntityPersister(final String entityName,
1417: final Object object) {
1418: errorIfClosed();
1419: if (entityName == null) {
1420: return factory.getEntityPersister(guessEntityName(object));
1421: } else {
1422: // try block is a hack around fact that currently tuplizers are not
1423: // given the opportunity to resolve a subclass entity name. this
1424: // allows the (we assume custom) interceptor the ability to
1425: // influence this decision if we were not able to based on the
1426: // given entityName
1427: try {
1428: return factory.getEntityPersister(entityName)
1429: .getSubclassEntityPersister(object,
1430: getFactory(), entityMode);
1431: } catch (HibernateException e) {
1432: try {
1433: return getEntityPersister(null, object);
1434: } catch (HibernateException e2) {
1435: throw e;
1436: }
1437: }
1438: }
1439: }
1440:
1441: // not for internal use:
1442: public Serializable getIdentifier(Object object)
1443: throws HibernateException {
1444: errorIfClosed();
1445: checkTransactionSynchStatus();
1446: if (object instanceof HibernateProxy) {
1447: LazyInitializer li = ((HibernateProxy) object)
1448: .getHibernateLazyInitializer();
1449: if (li.getSession() != this ) {
1450: throw new TransientObjectException(
1451: "The proxy was not associated with this session");
1452: }
1453: return li.getIdentifier();
1454: } else {
1455: EntityEntry entry = persistenceContext.getEntry(object);
1456: if (entry == null) {
1457: throw new TransientObjectException(
1458: "The instance was not associated with this session");
1459: }
1460: return entry.getId();
1461: }
1462: }
1463:
1464: /**
1465: * Get the id value for an object that is actually associated with the session. This
1466: * is a bit stricter than getEntityIdentifierIfNotUnsaved().
1467: */
1468: public Serializable getContextEntityIdentifier(Object object) {
1469: errorIfClosed();
1470: if (object instanceof HibernateProxy) {
1471: return getProxyIdentifier(object);
1472: } else {
1473: EntityEntry entry = persistenceContext.getEntry(object);
1474: return entry != null ? entry.getId() : null;
1475: }
1476: }
1477:
1478: private Serializable getProxyIdentifier(Object proxy) {
1479: return ((HibernateProxy) proxy).getHibernateLazyInitializer()
1480: .getIdentifier();
1481: }
1482:
1483: public Collection filter(Object collection, String filter)
1484: throws HibernateException {
1485: return listFilter(collection, filter, new QueryParameters(
1486: new Type[1], new Object[1]));
1487: }
1488:
1489: public Collection filter(Object collection, String filter,
1490: Object value, Type type) throws HibernateException {
1491: return listFilter(collection, filter,
1492: new QueryParameters(new Type[] { null, type },
1493: new Object[] { null, value }));
1494: }
1495:
1496: public Collection filter(Object collection, String filter,
1497: Object[] values, Type[] types) throws HibernateException {
1498: Object[] vals = new Object[values.length + 1];
1499: Type[] typs = new Type[types.length + 1];
1500: System.arraycopy(values, 0, vals, 1, values.length);
1501: System.arraycopy(types, 0, typs, 1, types.length);
1502: return listFilter(collection, filter, new QueryParameters(typs,
1503: vals));
1504: }
1505:
1506: private FilterQueryPlan getFilterQueryPlan(Object collection,
1507: String filter, QueryParameters parameters, boolean shallow)
1508: throws HibernateException {
1509: if (collection == null) {
1510: throw new NullPointerException(
1511: "null collection passed to filter");
1512: }
1513:
1514: CollectionEntry entry = persistenceContext
1515: .getCollectionEntryOrNull(collection);
1516: final CollectionPersister roleBeforeFlush = (entry == null) ? null
1517: : entry.getLoadedPersister();
1518:
1519: FilterQueryPlan plan = null;
1520: if (roleBeforeFlush == null) {
1521: // if it was previously unreferenced, we need to flush in order to
1522: // get its state into the database in order to execute query
1523: flush();
1524: entry = persistenceContext
1525: .getCollectionEntryOrNull(collection);
1526: CollectionPersister roleAfterFlush = (entry == null) ? null
1527: : entry.getLoadedPersister();
1528: if (roleAfterFlush == null) {
1529: throw new QueryException(
1530: "The collection was unreferenced");
1531: }
1532: plan = factory.getQueryPlanCache().getFilterQueryPlan(
1533: filter, roleAfterFlush.getRole(), shallow,
1534: getEnabledFilters());
1535: } else {
1536: // otherwise, we only need to flush if there are in-memory changes
1537: // to the queried tables
1538: plan = factory.getQueryPlanCache().getFilterQueryPlan(
1539: filter, roleBeforeFlush.getRole(), shallow,
1540: getEnabledFilters());
1541: if (autoFlushIfRequired(plan.getQuerySpaces())) {
1542: // might need to run a different filter entirely after the flush
1543: // because the collection role may have changed
1544: entry = persistenceContext
1545: .getCollectionEntryOrNull(collection);
1546: CollectionPersister roleAfterFlush = (entry == null) ? null
1547: : entry.getLoadedPersister();
1548: if (roleBeforeFlush != roleAfterFlush) {
1549: if (roleAfterFlush == null) {
1550: throw new QueryException(
1551: "The collection was dereferenced");
1552: }
1553: plan = factory.getQueryPlanCache()
1554: .getFilterQueryPlan(filter,
1555: roleAfterFlush.getRole(), shallow,
1556: getEnabledFilters());
1557: }
1558: }
1559: }
1560:
1561: if (parameters != null) {
1562: parameters.getPositionalParameterValues()[0] = entry
1563: .getLoadedKey();
1564: parameters.getPositionalParameterTypes()[0] = entry
1565: .getLoadedPersister().getKeyType();
1566: }
1567:
1568: return plan;
1569: }
1570:
1571: public List listFilter(Object collection, String filter,
1572: QueryParameters queryParameters) throws HibernateException {
1573: errorIfClosed();
1574: checkTransactionSynchStatus();
1575: FilterQueryPlan plan = getFilterQueryPlan(collection, filter,
1576: queryParameters, false);
1577: List results = CollectionHelper.EMPTY_LIST;
1578:
1579: boolean success = false;
1580: dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
1581: try {
1582: results = plan.performList(queryParameters, this );
1583: success = true;
1584: } finally {
1585: dontFlushFromFind--;
1586: afterOperation(success);
1587: }
1588: return results;
1589: }
1590:
1591: public Iterator iterateFilter(Object collection, String filter,
1592: QueryParameters queryParameters) throws HibernateException {
1593: errorIfClosed();
1594: checkTransactionSynchStatus();
1595: FilterQueryPlan plan = getFilterQueryPlan(collection, filter,
1596: queryParameters, true);
1597: return plan.performIterate(queryParameters, this );
1598: }
1599:
1600: public Criteria createCriteria(Class persistentClass, String alias) {
1601: errorIfClosed();
1602: checkTransactionSynchStatus();
1603: return new CriteriaImpl(persistentClass.getName(), alias, this );
1604: }
1605:
1606: public Criteria createCriteria(String entityName, String alias) {
1607: errorIfClosed();
1608: checkTransactionSynchStatus();
1609: return new CriteriaImpl(entityName, alias, this );
1610: }
1611:
1612: public Criteria createCriteria(Class persistentClass) {
1613: errorIfClosed();
1614: checkTransactionSynchStatus();
1615: return new CriteriaImpl(persistentClass.getName(), this );
1616: }
1617:
1618: public Criteria createCriteria(String entityName) {
1619: errorIfClosed();
1620: checkTransactionSynchStatus();
1621: return new CriteriaImpl(entityName, this );
1622: }
1623:
1624: public ScrollableResults scroll(CriteriaImpl criteria,
1625: ScrollMode scrollMode) {
1626: errorIfClosed();
1627: checkTransactionSynchStatus();
1628: String entityName = criteria.getEntityOrClassName();
1629: CriteriaLoader loader = new CriteriaLoader(
1630: getOuterJoinLoadable(entityName), factory, criteria,
1631: entityName, getEnabledFilters());
1632: autoFlushIfRequired(loader.getQuerySpaces());
1633: dontFlushFromFind++;
1634: try {
1635: return loader.scroll(this , scrollMode);
1636: } finally {
1637: dontFlushFromFind--;
1638: }
1639: }
1640:
1641: public List list(CriteriaImpl criteria) throws HibernateException {
1642: errorIfClosed();
1643: checkTransactionSynchStatus();
1644: String[] implementors = factory.getImplementors(criteria
1645: .getEntityOrClassName());
1646: int size = implementors.length;
1647:
1648: CriteriaLoader[] loaders = new CriteriaLoader[size];
1649: Set spaces = new HashSet();
1650: for (int i = 0; i < size; i++) {
1651:
1652: loaders[i] = new CriteriaLoader(
1653: getOuterJoinLoadable(implementors[i]), factory,
1654: criteria, implementors[i], getEnabledFilters());
1655:
1656: spaces.addAll(loaders[i].getQuerySpaces());
1657:
1658: }
1659:
1660: autoFlushIfRequired(spaces);
1661:
1662: List results = Collections.EMPTY_LIST;
1663: dontFlushFromFind++;
1664: boolean success = false;
1665: try {
1666: for (int i = 0; i < size; i++) {
1667: final List currentResults = loaders[i].list(this );
1668: currentResults.addAll(results);
1669: results = currentResults;
1670: }
1671: success = true;
1672: } finally {
1673: dontFlushFromFind--;
1674: afterOperation(success);
1675: }
1676:
1677: return results;
1678: }
1679:
1680: private OuterJoinLoadable getOuterJoinLoadable(String entityName)
1681: throws MappingException {
1682: EntityPersister persister = factory
1683: .getEntityPersister(entityName);
1684: if (!(persister instanceof OuterJoinLoadable)) {
1685: throw new MappingException(
1686: "class persister is not OuterJoinLoadable: "
1687: + entityName);
1688: }
1689: return (OuterJoinLoadable) persister;
1690: }
1691:
1692: public boolean contains(Object object) {
1693: errorIfClosed();
1694: checkTransactionSynchStatus();
1695: if (object instanceof HibernateProxy) {
1696: //do not use proxiesByKey, since not all
1697: //proxies that point to this session's
1698: //instances are in that collection!
1699: LazyInitializer li = ((HibernateProxy) object)
1700: .getHibernateLazyInitializer();
1701: if (li.isUninitialized()) {
1702: //if it is an uninitialized proxy, pointing
1703: //with this session, then when it is accessed,
1704: //the underlying instance will be "contained"
1705: return li.getSession() == this ;
1706: } else {
1707: //if it is initialized, see if the underlying
1708: //instance is contained, since we need to
1709: //account for the fact that it might have been
1710: //evicted
1711: object = li.getImplementation();
1712: }
1713: }
1714: // A session is considered to contain an entity only if the entity has
1715: // an entry in the session's persistence context and the entry reports
1716: // that the entity has not been removed
1717: EntityEntry entry = persistenceContext.getEntry(object);
1718: return entry != null && entry.getStatus() != Status.DELETED
1719: && entry.getStatus() != Status.GONE;
1720: }
1721:
1722: public Query createQuery(String queryString) {
1723: errorIfClosed();
1724: checkTransactionSynchStatus();
1725: return super .createQuery(queryString);
1726: }
1727:
1728: public SQLQuery createSQLQuery(String sql) {
1729: errorIfClosed();
1730: checkTransactionSynchStatus();
1731: return super .createSQLQuery(sql);
1732: }
1733:
1734: public Query createSQLQuery(String sql, String returnAlias,
1735: Class returnClass) {
1736: errorIfClosed();
1737: checkTransactionSynchStatus();
1738: return new SQLQueryImpl(sql, new String[] { returnAlias },
1739: new Class[] { returnClass }, this , factory
1740: .getQueryPlanCache().getSQLParameterMetadata(
1741: sql));
1742: }
1743:
1744: public Query createSQLQuery(String sql, String returnAliases[],
1745: Class returnClasses[]) {
1746: errorIfClosed();
1747: checkTransactionSynchStatus();
1748: return new SQLQueryImpl(sql, returnAliases, returnClasses,
1749: this , factory.getQueryPlanCache()
1750: .getSQLParameterMetadata(sql));
1751: }
1752:
1753: public ScrollableResults scrollCustomQuery(CustomQuery customQuery,
1754: QueryParameters queryParameters) throws HibernateException {
1755: errorIfClosed();
1756: checkTransactionSynchStatus();
1757:
1758: if (log.isTraceEnabled()) {
1759: log.trace("scroll SQL query: " + customQuery.getSQL());
1760: }
1761:
1762: CustomLoader loader = new CustomLoader(customQuery,
1763: getFactory());
1764:
1765: autoFlushIfRequired(loader.getQuerySpaces());
1766:
1767: dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
1768: try {
1769: return loader.scroll(queryParameters, this );
1770: } finally {
1771: dontFlushFromFind--;
1772: }
1773: }
1774:
1775: // basically just an adapted copy of find(CriteriaImpl)
1776: public List listCustomQuery(CustomQuery customQuery,
1777: QueryParameters queryParameters) throws HibernateException {
1778: errorIfClosed();
1779: checkTransactionSynchStatus();
1780:
1781: if (log.isTraceEnabled()) {
1782: log.trace("SQL query: " + customQuery.getSQL());
1783: }
1784:
1785: CustomLoader loader = new CustomLoader(customQuery,
1786: getFactory());
1787:
1788: autoFlushIfRequired(loader.getQuerySpaces());
1789:
1790: dontFlushFromFind++;
1791: boolean success = false;
1792: try {
1793: List results = loader.list(this , queryParameters);
1794: success = true;
1795: return results;
1796: } finally {
1797: dontFlushFromFind--;
1798: afterOperation(success);
1799: }
1800: }
1801:
1802: public SessionFactory getSessionFactory() {
1803: checkTransactionSynchStatus();
1804: return factory;
1805: }
1806:
1807: public void initializeCollection(PersistentCollection collection,
1808: boolean writing) throws HibernateException {
1809: errorIfClosed();
1810: checkTransactionSynchStatus();
1811: InitializeCollectionEventListener[] listener = listeners
1812: .getInitializeCollectionEventListeners();
1813: for (int i = 0; i < listener.length; i++) {
1814: listener[i]
1815: .onInitializeCollection(new InitializeCollectionEvent(
1816: collection, this ));
1817: }
1818: }
1819:
1820: public String bestGuessEntityName(Object object) {
1821: if (object instanceof HibernateProxy) {
1822: LazyInitializer initializer = ((HibernateProxy) object)
1823: .getHibernateLazyInitializer();
1824: // it is possible for this method to be called during flush processing,
1825: // so make certain that we do not accidently initialize an uninitialized proxy
1826: if (initializer.isUninitialized()) {
1827: return initializer.getEntityName();
1828: }
1829: object = initializer.getImplementation();
1830: }
1831: EntityEntry entry = persistenceContext.getEntry(object);
1832: if (entry == null) {
1833: return guessEntityName(object);
1834: } else {
1835: return entry.getPersister().getEntityName();
1836: }
1837: }
1838:
1839: public String getEntityName(Object object) {
1840: errorIfClosed();
1841: checkTransactionSynchStatus();
1842: if (object instanceof HibernateProxy) {
1843: if (!persistenceContext.containsProxy(object)) {
1844: throw new TransientObjectException(
1845: "proxy was not associated with the session");
1846: }
1847: object = ((HibernateProxy) object)
1848: .getHibernateLazyInitializer().getImplementation();
1849: }
1850:
1851: EntityEntry entry = persistenceContext.getEntry(object);
1852: if (entry == null) {
1853: throwTransientObjectException(object);
1854: }
1855: return entry.getPersister().getEntityName();
1856: }
1857:
1858: private void throwTransientObjectException(Object object)
1859: throws HibernateException {
1860: throw new TransientObjectException(
1861: "object references an unsaved transient instance - save the transient instance before flushing: "
1862: + guessEntityName(object));
1863: }
1864:
1865: public String guessEntityName(Object object)
1866: throws HibernateException {
1867: errorIfClosed();
1868: String entity = interceptor.getEntityName(object);
1869: if (entity == null) {
1870: if (object instanceof Map) {
1871: entity = (String) ((Map) object)
1872: .get(DynamicMapInstantiator.KEY);
1873: if (entity == null) {
1874: throw new HibernateException(
1875: "could not determine type of dynamic entity");
1876: }
1877: } else if (object instanceof Element) {
1878: // TODO : really need to keep a map of nodeName -> entityName, but that would mean nodeName being distinct
1879: entity = ((Element) object).getName();
1880: } else {
1881: entity = object.getClass().getName();
1882: }
1883: }
1884: return entity;
1885: }
1886:
1887: public void cancelQuery() throws HibernateException {
1888: errorIfClosed();
1889: getBatcher().cancelLastQuery();
1890: }
1891:
1892: public Interceptor getInterceptor() {
1893: checkTransactionSynchStatus();
1894: return interceptor;
1895: }
1896:
1897: public int getDontFlushFromFind() {
1898: return dontFlushFromFind;
1899: }
1900:
1901: public String toString() {
1902: StringBuffer buf = new StringBuffer(500).append("SessionImpl(");
1903: if (!isClosed()) {
1904: buf.append(persistenceContext).append(";").append(
1905: actionQueue);
1906: } else {
1907: buf.append("<closed>");
1908: }
1909: return buf.append(')').toString();
1910: }
1911:
1912: public EventListeners getListeners() {
1913: return listeners;
1914: }
1915:
1916: public ActionQueue getActionQueue() {
1917: errorIfClosed();
1918: checkTransactionSynchStatus();
1919: return actionQueue;
1920: }
1921:
1922: public PersistenceContext getPersistenceContext() {
1923: errorIfClosed();
1924: checkTransactionSynchStatus();
1925: return persistenceContext;
1926: }
1927:
1928: public SessionStatistics getStatistics() {
1929: checkTransactionSynchStatus();
1930: return new SessionStatisticsImpl(this );
1931: }
1932:
1933: public boolean isEventSource() {
1934: checkTransactionSynchStatus();
1935: return true;
1936: }
1937:
1938: public void setReadOnly(Object entity, boolean readOnly) {
1939: errorIfClosed();
1940: checkTransactionSynchStatus();
1941: persistenceContext.setReadOnly(entity, readOnly);
1942: }
1943:
1944: public void afterScrollOperation() {
1945: // nothing to do in a stateful session
1946: }
1947:
1948: public String getFetchProfile() {
1949: checkTransactionSynchStatus();
1950: return fetchProfile;
1951: }
1952:
1953: public JDBCContext getJDBCContext() {
1954: errorIfClosed();
1955: checkTransactionSynchStatus();
1956: return jdbcContext;
1957: }
1958:
1959: public void setFetchProfile(String fetchProfile) {
1960: errorIfClosed();
1961: checkTransactionSynchStatus();
1962: this .fetchProfile = fetchProfile;
1963: }
1964:
1965: private void checkTransactionSynchStatus() {
1966: if (jdbcContext != null && !isClosed()) {
1967: jdbcContext.registerSynchronizationIfPossible();
1968: }
1969: }
1970:
1971: /**
1972: * Used by JDK serialization...
1973: *
1974: * @param ois The input stream from which we are being read...
1975: * @throws IOException Indicates a general IO stream exception
1976: * @throws ClassNotFoundException Indicates a class resolution issue
1977: */
1978: private void readObject(ObjectInputStream ois) throws IOException,
1979: ClassNotFoundException {
1980: log.trace("deserializing session");
1981:
1982: boolean isRootSession = ois.readBoolean();
1983: connectionReleaseMode = ConnectionReleaseMode
1984: .parse((String) ois.readObject());
1985: entityMode = EntityMode.parse((String) ois.readObject());
1986: autoClear = ois.readBoolean();
1987: flushMode = FlushMode.parse((String) ois.readObject());
1988: cacheMode = CacheMode.parse((String) ois.readObject());
1989: flushBeforeCompletionEnabled = ois.readBoolean();
1990: autoCloseSessionEnabled = ois.readBoolean();
1991: fetchProfile = (String) ois.readObject();
1992: interceptor = (Interceptor) ois.readObject();
1993:
1994: factory = SessionFactoryImpl.deserialize(ois);
1995: listeners = factory.getEventListeners();
1996:
1997: if (isRootSession) {
1998: jdbcContext = JDBCContext.deserialize(ois, this ,
1999: interceptor);
2000: }
2001:
2002: persistenceContext = StatefulPersistenceContext.deserialize(
2003: ois, this );
2004: actionQueue = ActionQueue.deserialize(ois, this );
2005:
2006: enabledFilters = (Map) ois.readObject();
2007: childSessionsByEntityMode = (Map) ois.readObject();
2008:
2009: Iterator iter = enabledFilters.values().iterator();
2010: while (iter.hasNext()) {
2011: ((FilterImpl) iter.next()).afterDeserialize(factory);
2012: }
2013:
2014: if (isRootSession && childSessionsByEntityMode != null) {
2015: iter = childSessionsByEntityMode.values().iterator();
2016: while (iter.hasNext()) {
2017: final SessionImpl child = ((SessionImpl) iter.next());
2018: child.rootSession = this ;
2019: child.jdbcContext = this .jdbcContext;
2020: }
2021: }
2022: }
2023:
2024: /**
2025: * Used by JDK serialization...
2026: *
2027: * @param oos The output stream to which we are being written...
2028: * @throws IOException Indicates a general IO stream exception
2029: */
2030: private void writeObject(ObjectOutputStream oos) throws IOException {
2031: if (!jdbcContext.getConnectionManager()
2032: .isReadyForSerialization()) {
2033: throw new IllegalStateException(
2034: "Cannot serialize a session while connected");
2035: }
2036:
2037: log.trace("serializing session");
2038:
2039: oos.writeBoolean(rootSession == null);
2040: oos.writeObject(connectionReleaseMode.toString());
2041: oos.writeObject(entityMode.toString());
2042: oos.writeBoolean(autoClear);
2043: oos.writeObject(flushMode.toString());
2044: oos.writeObject(cacheMode.toString());
2045: oos.writeBoolean(flushBeforeCompletionEnabled);
2046: oos.writeBoolean(autoCloseSessionEnabled);
2047: oos.writeObject(fetchProfile);
2048: // we need to writeObject() on this since interceptor is user defined
2049: oos.writeObject(interceptor);
2050:
2051: factory.serialize(oos);
2052:
2053: if (rootSession == null) {
2054: jdbcContext.serialize(oos);
2055: }
2056:
2057: persistenceContext.serialize(oos);
2058: actionQueue.serialize(oos);
2059:
2060: // todo : look at optimizing these...
2061: oos.writeObject(enabledFilters);
2062: oos.writeObject(childSessionsByEntityMode);
2063: }
2064: }
|