Source Code Cross Referenced for StatefulPersistenceContext.java in  » Database-ORM » hibernate » org » hibernate » engine » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » hibernate » org.hibernate.engine 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        // $Id: StatefulPersistenceContext.java 11489 2007-05-09 01:42:44Z steve.ebersole@jboss.com $
0002:        package org.hibernate.engine;
0003:
0004:        import java.io.IOException;
0005:        import java.io.InvalidObjectException;
0006:        import java.io.ObjectInputStream;
0007:        import java.io.ObjectOutputStream;
0008:        import java.io.Serializable;
0009:        import java.util.ArrayList;
0010:        import java.util.HashMap;
0011:        import java.util.HashSet;
0012:        import java.util.Iterator;
0013:        import java.util.List;
0014:        import java.util.Map;
0015:
0016:        import org.apache.commons.collections.ReferenceMap;
0017:        import org.apache.commons.logging.Log;
0018:        import org.apache.commons.logging.LogFactory;
0019:        import org.hibernate.AssertionFailure;
0020:        import org.hibernate.Hibernate;
0021:        import org.hibernate.HibernateException;
0022:        import org.hibernate.LockMode;
0023:        import org.hibernate.MappingException;
0024:        import org.hibernate.NonUniqueObjectException;
0025:        import org.hibernate.PersistentObjectException;
0026:        import org.hibernate.TransientObjectException;
0027:        import org.hibernate.engine.loading.LoadContexts;
0028:        import org.hibernate.pretty.MessageHelper;
0029:        import org.hibernate.collection.PersistentCollection;
0030:        import org.hibernate.persister.collection.CollectionPersister;
0031:        import org.hibernate.persister.entity.EntityPersister;
0032:        import org.hibernate.proxy.HibernateProxy;
0033:        import org.hibernate.proxy.LazyInitializer;
0034:        import org.hibernate.tuple.ElementWrapper;
0035:        import org.hibernate.util.IdentityMap;
0036:        import org.hibernate.util.MarkerObject;
0037:
0038:        /**
0039:         * A <tt>PersistenceContext</tt> represents the state of persistent "stuff" which
0040:         * Hibernate is tracking.  This includes persistent entities, collections,
0041:         * as well as proxies generated.
0042:         * </p>
0043:         * There is meant to be a one-to-one correspondence between a SessionImpl and
0044:         * a PersistentContext.  The SessionImpl uses the PersistentContext to track
0045:         * the current state of its context.  Event-listeners then use the
0046:         * PersistentContext to drive their processing.
0047:         *
0048:         * @author Steve Ebersole
0049:         */
0050:        public class StatefulPersistenceContext implements  PersistenceContext {
0051:
0052:            public static final Object NO_ROW = new MarkerObject("NO_ROW");
0053:
0054:            private static final Log log = LogFactory
0055:                    .getLog(StatefulPersistenceContext.class);
0056:            private static final Log PROXY_WARN_LOG = LogFactory
0057:                    .getLog(StatefulPersistenceContext.class.getName()
0058:                            + ".ProxyWarnLog");
0059:            private static final int INIT_COLL_SIZE = 8;
0060:
0061:            private SessionImplementor session;
0062:
0063:            // Loaded entity instances, by EntityKey
0064:            private Map entitiesByKey;
0065:
0066:            // Loaded entity instances, by EntityUniqueKey
0067:            private Map entitiesByUniqueKey;
0068:
0069:            // Identity map of EntityEntry instances, by the entity instance
0070:            private Map entityEntries;
0071:
0072:            // Entity proxies, by EntityKey
0073:            private Map proxiesByKey;
0074:
0075:            // Snapshots of current database state for entities
0076:            // that have *not* been loaded
0077:            private Map entitySnapshotsByKey;
0078:
0079:            // Identity map of array holder ArrayHolder instances, by the array instance
0080:            private Map arrayHolders;
0081:
0082:            // Identity map of CollectionEntry instances, by the collection wrapper
0083:            private Map collectionEntries;
0084:
0085:            // Collection wrappers, by the CollectionKey
0086:            private Map collectionsByKey; //key=CollectionKey, value=PersistentCollection
0087:
0088:            // Set of EntityKeys of deleted objects
0089:            private HashSet nullifiableEntityKeys;
0090:
0091:            // properties that we have tried to load, and not found in the database
0092:            private HashSet nullAssociations;
0093:
0094:            // A list of collection wrappers that were instantiating during result set
0095:            // processing, that we will need to initialize at the end of the query
0096:            private List nonlazyCollections;
0097:
0098:            // A container for collections we load up when the owning entity is not
0099:            // yet loaded ... for now, this is purely transient!
0100:            private Map unownedCollections;
0101:
0102:            private int cascading = 0;
0103:            private int loadCounter = 0;
0104:            private boolean flushing = false;
0105:
0106:            private boolean hasNonReadOnlyEntities = false;
0107:
0108:            private LoadContexts loadContexts;
0109:            private BatchFetchQueue batchFetchQueue;
0110:
0111:            /**
0112:             * Constructs a PersistentContext, bound to the given session.
0113:             *
0114:             * @param session The session "owning" this context.
0115:             */
0116:            public StatefulPersistenceContext(SessionImplementor session) {
0117:                this .session = session;
0118:
0119:                entitiesByKey = new HashMap(INIT_COLL_SIZE);
0120:                entitiesByUniqueKey = new HashMap(INIT_COLL_SIZE);
0121:                proxiesByKey = new ReferenceMap(ReferenceMap.HARD,
0122:                        ReferenceMap.WEAK);
0123:                entitySnapshotsByKey = new HashMap(INIT_COLL_SIZE);
0124:
0125:                entityEntries = IdentityMap
0126:                        .instantiateSequenced(INIT_COLL_SIZE);
0127:                collectionEntries = IdentityMap
0128:                        .instantiateSequenced(INIT_COLL_SIZE);
0129:                collectionsByKey = new HashMap(INIT_COLL_SIZE);
0130:                arrayHolders = IdentityMap.instantiate(INIT_COLL_SIZE);
0131:
0132:                nullifiableEntityKeys = new HashSet();
0133:
0134:                initTransientState();
0135:            }
0136:
0137:            private void initTransientState() {
0138:                nullAssociations = new HashSet(INIT_COLL_SIZE);
0139:                nonlazyCollections = new ArrayList(INIT_COLL_SIZE);
0140:            }
0141:
0142:            public boolean isStateless() {
0143:                return false;
0144:            }
0145:
0146:            public SessionImplementor getSession() {
0147:                return session;
0148:            }
0149:
0150:            public LoadContexts getLoadContexts() {
0151:                if (loadContexts == null) {
0152:                    loadContexts = new LoadContexts(this );
0153:                }
0154:                return loadContexts;
0155:            }
0156:
0157:            public void addUnownedCollection(CollectionKey key,
0158:                    PersistentCollection collection) {
0159:                if (unownedCollections == null) {
0160:                    unownedCollections = new HashMap(8);
0161:                }
0162:                unownedCollections.put(key, collection);
0163:            }
0164:
0165:            public PersistentCollection useUnownedCollection(CollectionKey key) {
0166:                if (unownedCollections == null) {
0167:                    return null;
0168:                } else {
0169:                    return (PersistentCollection) unownedCollections
0170:                            .remove(key);
0171:                }
0172:            }
0173:
0174:            /**
0175:             * Get the <tt>BatchFetchQueue</tt>, instantiating one if
0176:             * necessary.
0177:             */
0178:            public BatchFetchQueue getBatchFetchQueue() {
0179:                if (batchFetchQueue == null) {
0180:                    batchFetchQueue = new BatchFetchQueue(this );
0181:                }
0182:                return batchFetchQueue;
0183:            }
0184:
0185:            public void clear() {
0186:                Iterator itr = proxiesByKey.values().iterator();
0187:                while (itr.hasNext()) {
0188:                    final LazyInitializer li = ((HibernateProxy) itr.next())
0189:                            .getHibernateLazyInitializer();
0190:                    li.setSession(null);
0191:                }
0192:                Map.Entry[] collectionEntryArray = IdentityMap
0193:                        .concurrentEntries(collectionEntries);
0194:                for (int i = 0; i < collectionEntryArray.length; i++) {
0195:                    ((PersistentCollection) collectionEntryArray[i].getKey())
0196:                            .unsetSession(getSession());
0197:                }
0198:                arrayHolders.clear();
0199:                entitiesByKey.clear();
0200:                entitiesByUniqueKey.clear();
0201:                entityEntries.clear();
0202:                entitySnapshotsByKey.clear();
0203:                collectionsByKey.clear();
0204:                collectionEntries.clear();
0205:                if (unownedCollections != null) {
0206:                    unownedCollections.clear();
0207:                }
0208:                proxiesByKey.clear();
0209:                nullifiableEntityKeys.clear();
0210:                if (batchFetchQueue != null) {
0211:                    batchFetchQueue.clear();
0212:                }
0213:                hasNonReadOnlyEntities = false;
0214:            }
0215:
0216:            public boolean hasNonReadOnlyEntities() {
0217:                return hasNonReadOnlyEntities;
0218:            }
0219:
0220:            public void setEntryStatus(EntityEntry entry, Status status) {
0221:                entry.setStatus(status);
0222:                setHasNonReadOnlyEnties(status);
0223:            }
0224:
0225:            private void setHasNonReadOnlyEnties(Status status) {
0226:                if (status == Status.DELETED || status == Status.MANAGED
0227:                        || status == Status.SAVING) {
0228:                    hasNonReadOnlyEntities = true;
0229:                }
0230:            }
0231:
0232:            public void afterTransactionCompletion() {
0233:                // Downgrade locks
0234:                Iterator iter = entityEntries.values().iterator();
0235:                while (iter.hasNext()) {
0236:                    ((EntityEntry) iter.next()).setLockMode(LockMode.NONE);
0237:                }
0238:            }
0239:
0240:            /**
0241:             * Get the current state of the entity as known to the underlying
0242:             * database, or null if there is no corresponding row 
0243:             */
0244:            public Object[] getDatabaseSnapshot(Serializable id,
0245:                    EntityPersister persister) throws HibernateException {
0246:                EntityKey key = new EntityKey(id, persister, session
0247:                        .getEntityMode());
0248:                Object cached = entitySnapshotsByKey.get(key);
0249:                if (cached != null) {
0250:                    return cached == NO_ROW ? null : (Object[]) cached;
0251:                } else {
0252:                    Object[] snapshot = persister.getDatabaseSnapshot(id,
0253:                            session);
0254:                    entitySnapshotsByKey.put(key, snapshot == null ? NO_ROW
0255:                            : snapshot);
0256:                    return snapshot;
0257:                }
0258:            }
0259:
0260:            public Object[] getNaturalIdSnapshot(Serializable id,
0261:                    EntityPersister persister) throws HibernateException {
0262:                if (!persister.hasNaturalIdentifier()) {
0263:                    return null;
0264:                }
0265:
0266:                // if the natural-id is marked as non-mutable, it is not retrieved during a
0267:                // normal database-snapshot operation...
0268:                int[] props = persister.getNaturalIdentifierProperties();
0269:                boolean[] updateable = persister.getPropertyUpdateability();
0270:                boolean allNatualIdPropsAreUpdateable = true;
0271:                for (int i = 0; i < props.length; i++) {
0272:                    if (!updateable[props[i]]) {
0273:                        allNatualIdPropsAreUpdateable = false;
0274:                        break;
0275:                    }
0276:                }
0277:
0278:                if (allNatualIdPropsAreUpdateable) {
0279:                    // do this when all the properties are updateable since there is
0280:                    // a certain likelihood that the information will already be
0281:                    // snapshot-cached.
0282:                    Object[] entitySnapshot = getDatabaseSnapshot(id, persister);
0283:                    if (entitySnapshot == NO_ROW) {
0284:                        return null;
0285:                    }
0286:                    Object[] naturalIdSnapshot = new Object[props.length];
0287:                    for (int i = 0; i < props.length; i++) {
0288:                        naturalIdSnapshot[i] = entitySnapshot[props[i]];
0289:                    }
0290:                    return naturalIdSnapshot;
0291:                } else {
0292:                    return persister.getNaturalIdentifierSnapshot(id, session);
0293:                }
0294:            }
0295:
0296:            /**
0297:             * Retrieve the cached database snapshot for the requested entity key.
0298:             * <p/>
0299:             * This differs from {@link #getDatabaseSnapshot} is two important respects:<ol>
0300:             * <li>no snapshot is obtained from the database if not already cached</li>
0301:             * <li>an entry of {@link #NO_ROW} here is interpretet as an exception</li>
0302:             * </ol>
0303:             * @param key The entity key for which to retrieve the cached snapshot
0304:             * @return The cached snapshot
0305:             * @throws IllegalStateException if the cached snapshot was == {@link #NO_ROW}.
0306:             */
0307:            public Object[] getCachedDatabaseSnapshot(EntityKey key) {
0308:                Object snapshot = entitySnapshotsByKey.get(key);
0309:                if (snapshot == NO_ROW) {
0310:                    throw new IllegalStateException(
0311:                            "persistence context reported no row snapshot for "
0312:                                    + MessageHelper.infoString(key
0313:                                            .getEntityName(), key
0314:                                            .getIdentifier()));
0315:                }
0316:                return (Object[]) snapshot;
0317:            }
0318:
0319:            /*public void removeDatabaseSnapshot(EntityKey key) {
0320:            	entitySnapshotsByKey.remove(key);
0321:            }*/
0322:
0323:            public void addEntity(EntityKey key, Object entity) {
0324:                entitiesByKey.put(key, entity);
0325:                getBatchFetchQueue().removeBatchLoadableEntityKey(key);
0326:            }
0327:
0328:            /**
0329:             * Get the entity instance associated with the given 
0330:             * <tt>EntityKey</tt>
0331:             */
0332:            public Object getEntity(EntityKey key) {
0333:                return entitiesByKey.get(key);
0334:            }
0335:
0336:            public boolean containsEntity(EntityKey key) {
0337:                return entitiesByKey.containsKey(key);
0338:            }
0339:
0340:            /**
0341:             * Remove an entity from the session cache, also clear
0342:             * up other state associated with the entity, all except
0343:             * for the <tt>EntityEntry</tt>
0344:             */
0345:            public Object removeEntity(EntityKey key) {
0346:                Object entity = entitiesByKey.remove(key);
0347:                Iterator iter = entitiesByUniqueKey.values().iterator();
0348:                while (iter.hasNext()) {
0349:                    if (iter.next() == entity)
0350:                        iter.remove();
0351:                }
0352:                entitySnapshotsByKey.remove(key);
0353:                nullifiableEntityKeys.remove(key);
0354:                getBatchFetchQueue().removeBatchLoadableEntityKey(key);
0355:                getBatchFetchQueue().removeSubselect(key);
0356:                return entity;
0357:            }
0358:
0359:            /**
0360:             * Get an entity cached by unique key
0361:             */
0362:            public Object getEntity(EntityUniqueKey euk) {
0363:                return entitiesByUniqueKey.get(euk);
0364:            }
0365:
0366:            /**
0367:             * Add an entity to the cache by unique key
0368:             */
0369:            public void addEntity(EntityUniqueKey euk, Object entity) {
0370:                entitiesByUniqueKey.put(euk, entity);
0371:            }
0372:
0373:            /**
0374:             * Retreive the EntityEntry representation of the given entity.
0375:             *
0376:             * @param entity The entity for which to locate the EntityEntry.
0377:             * @return The EntityEntry for the given entity.
0378:             */
0379:            public EntityEntry getEntry(Object entity) {
0380:                return (EntityEntry) entityEntries.get(entity);
0381:            }
0382:
0383:            /**
0384:             * Remove an entity entry from the session cache
0385:             */
0386:            public EntityEntry removeEntry(Object entity) {
0387:                return (EntityEntry) entityEntries.remove(entity);
0388:            }
0389:
0390:            /**
0391:             * Is there an EntityEntry for this instance?
0392:             */
0393:            public boolean isEntryFor(Object entity) {
0394:                return entityEntries.containsKey(entity);
0395:            }
0396:
0397:            /**
0398:             * Get the collection entry for a persistent collection
0399:             */
0400:            public CollectionEntry getCollectionEntry(PersistentCollection coll) {
0401:                return (CollectionEntry) collectionEntries.get(coll);
0402:            }
0403:
0404:            /**
0405:             * Adds an entity to the internal caches.
0406:             */
0407:            public EntityEntry addEntity(final Object entity,
0408:                    final Status status, final Object[] loadedState,
0409:                    final EntityKey entityKey, final Object version,
0410:                    final LockMode lockMode, final boolean existsInDatabase,
0411:                    final EntityPersister persister,
0412:                    final boolean disableVersionIncrement,
0413:                    boolean lazyPropertiesAreUnfetched) {
0414:
0415:                addEntity(entityKey, entity);
0416:
0417:                return addEntry(entity, status, loadedState, null, entityKey
0418:                        .getIdentifier(), version, lockMode, existsInDatabase,
0419:                        persister, disableVersionIncrement,
0420:                        lazyPropertiesAreUnfetched);
0421:            }
0422:
0423:            /**
0424:             * Generates an appropriate EntityEntry instance and adds it 
0425:             * to the event source's internal caches.
0426:             */
0427:            public EntityEntry addEntry(final Object entity,
0428:                    final Status status, final Object[] loadedState,
0429:                    final Object rowId, final Serializable id,
0430:                    final Object version, final LockMode lockMode,
0431:                    final boolean existsInDatabase,
0432:                    final EntityPersister persister,
0433:                    final boolean disableVersionIncrement,
0434:                    boolean lazyPropertiesAreUnfetched) {
0435:
0436:                EntityEntry e = new EntityEntry(status, loadedState, rowId, id,
0437:                        version, lockMode, existsInDatabase, persister, session
0438:                                .getEntityMode(), disableVersionIncrement,
0439:                        lazyPropertiesAreUnfetched);
0440:                entityEntries.put(entity, e);
0441:
0442:                setHasNonReadOnlyEnties(status);
0443:                return e;
0444:            }
0445:
0446:            public boolean containsCollection(PersistentCollection collection) {
0447:                return collectionEntries.containsKey(collection);
0448:            }
0449:
0450:            public boolean containsProxy(Object entity) {
0451:                return proxiesByKey.containsValue(entity);
0452:            }
0453:
0454:            /**
0455:             * Takes the given object and, if it represents a proxy, reassociates it with this event source.
0456:             *
0457:             * @param value The possible proxy to be reassociated.
0458:             * @return Whether the passed value represented an actual proxy which got initialized.
0459:             * @throws MappingException
0460:             */
0461:            public boolean reassociateIfUninitializedProxy(Object value)
0462:                    throws MappingException {
0463:                if (value instanceof  ElementWrapper) {
0464:                    value = ((ElementWrapper) value).getElement();
0465:                }
0466:
0467:                if (!Hibernate.isInitialized(value)) {
0468:                    HibernateProxy proxy = (HibernateProxy) value;
0469:                    LazyInitializer li = proxy.getHibernateLazyInitializer();
0470:                    reassociateProxy(li, proxy);
0471:                    return true;
0472:                } else {
0473:                    return false;
0474:                }
0475:            }
0476:
0477:            /**
0478:             * If a deleted entity instance is re-saved, and it has a proxy, we need to
0479:             * reset the identifier of the proxy 
0480:             */
0481:            public void reassociateProxy(Object value, Serializable id)
0482:                    throws MappingException {
0483:                if (value instanceof  ElementWrapper) {
0484:                    value = ((ElementWrapper) value).getElement();
0485:                }
0486:
0487:                if (value instanceof  HibernateProxy) {
0488:                    if (log.isDebugEnabled())
0489:                        log.debug("setting proxy identifier: " + id);
0490:                    HibernateProxy proxy = (HibernateProxy) value;
0491:                    LazyInitializer li = proxy.getHibernateLazyInitializer();
0492:                    li.setIdentifier(id);
0493:                    reassociateProxy(li, proxy);
0494:                }
0495:            }
0496:
0497:            /**
0498:             * Associate a proxy that was instantiated by another session with this session
0499:             *
0500:             * @param li The proxy initializer.
0501:             * @param proxy The proxy to reassociate.
0502:             */
0503:            private void reassociateProxy(LazyInitializer li,
0504:                    HibernateProxy proxy) {
0505:                if (li.getSession() != this .getSession()) {
0506:                    EntityPersister persister = session.getFactory()
0507:                            .getEntityPersister(li.getEntityName());
0508:                    EntityKey key = new EntityKey(li.getIdentifier(),
0509:                            persister, session.getEntityMode());
0510:                    // any earlier proxy takes precedence
0511:                    if (!proxiesByKey.containsKey(key)) {
0512:                        proxiesByKey.put(key, proxy);
0513:                    }
0514:                    proxy.getHibernateLazyInitializer().setSession(session);
0515:                }
0516:            }
0517:
0518:            /**
0519:             * Get the entity instance underlying the given proxy, throwing
0520:             * an exception if the proxy is uninitialized. If the given object
0521:             * is not a proxy, simply return the argument.
0522:             */
0523:            public Object unproxy(Object maybeProxy) throws HibernateException {
0524:                if (maybeProxy instanceof  ElementWrapper) {
0525:                    maybeProxy = ((ElementWrapper) maybeProxy).getElement();
0526:                }
0527:
0528:                if (maybeProxy instanceof  HibernateProxy) {
0529:                    HibernateProxy proxy = (HibernateProxy) maybeProxy;
0530:                    LazyInitializer li = proxy.getHibernateLazyInitializer();
0531:                    if (li.isUninitialized()) {
0532:                        throw new PersistentObjectException(
0533:                                "object was an uninitialized proxy for "
0534:                                        + li.getEntityName());
0535:                    }
0536:                    return li.getImplementation(); //unwrap the object
0537:                } else {
0538:                    return maybeProxy;
0539:                }
0540:            }
0541:
0542:            /**
0543:             * Possibly unproxy the given reference and reassociate it with the current session.
0544:             *
0545:             * @param maybeProxy The reference to be unproxied if it currently represents a proxy.
0546:             * @return The unproxied instance.
0547:             * @throws HibernateException
0548:             */
0549:            public Object unproxyAndReassociate(Object maybeProxy)
0550:                    throws HibernateException {
0551:                if (maybeProxy instanceof  ElementWrapper) {
0552:                    maybeProxy = ((ElementWrapper) maybeProxy).getElement();
0553:                }
0554:
0555:                if (maybeProxy instanceof  HibernateProxy) {
0556:                    HibernateProxy proxy = (HibernateProxy) maybeProxy;
0557:                    LazyInitializer li = proxy.getHibernateLazyInitializer();
0558:                    reassociateProxy(li, proxy);
0559:                    return li.getImplementation(); //initialize + unwrap the object
0560:                } else {
0561:                    return maybeProxy;
0562:                }
0563:            }
0564:
0565:            /**
0566:             * Attempts to check whether the given key represents an entity already loaded within the
0567:             * current session.
0568:             * @param object The entity reference against which to perform the uniqueness check.
0569:             * @throws HibernateException
0570:             */
0571:            public void checkUniqueness(EntityKey key, Object object)
0572:                    throws HibernateException {
0573:                Object entity = getEntity(key);
0574:                if (entity == object) {
0575:                    throw new AssertionFailure(
0576:                            "object already associated, but no entry was found");
0577:                }
0578:                if (entity != null) {
0579:                    throw new NonUniqueObjectException(key.getIdentifier(), key
0580:                            .getEntityName());
0581:                }
0582:            }
0583:
0584:            /**
0585:             * If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy
0586:             * and overwrite the registration of the old one. This breaks == and occurs only for
0587:             * "class" proxies rather than "interface" proxies. Also init the proxy to point to
0588:             * the given target implementation if necessary.
0589:             *
0590:             * @param proxy The proxy instance to be narrowed.
0591:             * @param persister The persister for the proxied entity.
0592:             * @param key The internal cache key for the proxied entity.
0593:             * @param object (optional) the actual proxied entity instance.
0594:             * @return An appropriately narrowed instance.
0595:             * @throws HibernateException
0596:             */
0597:            public Object narrowProxy(Object proxy, EntityPersister persister,
0598:                    EntityKey key, Object object) throws HibernateException {
0599:
0600:                boolean alreadyNarrow = persister.getConcreteProxyClass(
0601:                        session.getEntityMode()).isAssignableFrom(
0602:                        proxy.getClass());
0603:
0604:                if (!alreadyNarrow) {
0605:                    if (PROXY_WARN_LOG.isWarnEnabled()) {
0606:                        PROXY_WARN_LOG.warn("Narrowing proxy to "
0607:                                + persister.getConcreteProxyClass(session
0608:                                        .getEntityMode())
0609:                                + " - this operation breaks ==");
0610:                    }
0611:
0612:                    if (object != null) {
0613:                        proxiesByKey.remove(key);
0614:                        return object; //return the proxied object
0615:                    } else {
0616:                        proxy = persister.createProxy(key.getIdentifier(),
0617:                                session);
0618:                        proxiesByKey.put(key, proxy); //overwrite old proxy
0619:                        return proxy;
0620:                    }
0621:
0622:                } else {
0623:
0624:                    if (object != null) {
0625:                        LazyInitializer li = ((HibernateProxy) proxy)
0626:                                .getHibernateLazyInitializer();
0627:                        li.setImplementation(object);
0628:                    }
0629:
0630:                    return proxy;
0631:
0632:                }
0633:
0634:            }
0635:
0636:            /**
0637:             * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
0638:             * third argument (the entity associated with the key) if no proxy exists. Init
0639:             * the proxy to the target implementation, if necessary.
0640:             */
0641:            public Object proxyFor(EntityPersister persister, EntityKey key,
0642:                    Object impl) throws HibernateException {
0643:                if (!persister.hasProxy())
0644:                    return impl;
0645:                Object proxy = proxiesByKey.get(key);
0646:                if (proxy != null) {
0647:                    return narrowProxy(proxy, persister, key, impl);
0648:                } else {
0649:                    return impl;
0650:                }
0651:            }
0652:
0653:            /**
0654:             * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
0655:             * argument (the entity associated with the key) if no proxy exists.
0656:             * (slower than the form above)
0657:             */
0658:            public Object proxyFor(Object impl) throws HibernateException {
0659:                EntityEntry e = getEntry(impl);
0660:                EntityPersister p = e.getPersister();
0661:                return proxyFor(p, new EntityKey(e.getId(), p, session
0662:                        .getEntityMode()), impl);
0663:            }
0664:
0665:            /**
0666:             * Get the entity that owns this persistent collection
0667:             */
0668:            public Object getCollectionOwner(Serializable key,
0669:                    CollectionPersister collectionPersister)
0670:                    throws MappingException {
0671:                return getEntity(new EntityKey(key, collectionPersister
0672:                        .getOwnerEntityPersister(), session.getEntityMode()));
0673:            }
0674:
0675:            /**
0676:             * add a collection we just loaded up (still needs initializing)
0677:             */
0678:            public void addUninitializedCollection(
0679:                    CollectionPersister persister,
0680:                    PersistentCollection collection, Serializable id) {
0681:                CollectionEntry ce = new CollectionEntry(collection, persister,
0682:                        id, flushing);
0683:                addCollection(collection, ce, id);
0684:            }
0685:
0686:            /**
0687:             * add a detached uninitialized collection
0688:             */
0689:            public void addUninitializedDetachedCollection(
0690:                    CollectionPersister persister,
0691:                    PersistentCollection collection) {
0692:                CollectionEntry ce = new CollectionEntry(persister, collection
0693:                        .getKey());
0694:                addCollection(collection, ce, collection.getKey());
0695:            }
0696:
0697:            /**
0698:             * Add a new collection (ie. a newly created one, just instantiated by the
0699:             * application, with no database state or snapshot)
0700:             * @param collection The collection to be associated with the persistence context
0701:             */
0702:            public void addNewCollection(CollectionPersister persister,
0703:                    PersistentCollection collection) throws HibernateException {
0704:                addCollection(collection, persister);
0705:            }
0706:
0707:            /**
0708:             * Add an collection to the cache, with a given collection entry.
0709:             *
0710:             * @param coll The collection for which we are adding an entry.
0711:             * @param entry The entry representing the collection.
0712:             * @param key The key of the collection's entry.
0713:             */
0714:            private void addCollection(PersistentCollection coll,
0715:                    CollectionEntry entry, Serializable key) {
0716:                collectionEntries.put(coll, entry);
0717:                CollectionKey collectionKey = new CollectionKey(entry
0718:                        .getLoadedPersister(), key, session.getEntityMode());
0719:                PersistentCollection old = (PersistentCollection) collectionsByKey
0720:                        .put(collectionKey, coll);
0721:                if (old != null) {
0722:                    if (old == coll) {
0723:                        throw new AssertionFailure(
0724:                                "bug adding collection twice");
0725:                    }
0726:                    // or should it actually throw an exception?
0727:                    old.unsetSession(session);
0728:                    collectionEntries.remove(old);
0729:                    // watch out for a case where old is still referenced
0730:                    // somewhere in the object graph! (which is a user error)
0731:                }
0732:            }
0733:
0734:            /**
0735:             * Add a collection to the cache, creating a new collection entry for it
0736:             *
0737:             * @param collection The collection for which we are adding an entry.
0738:             * @param persister The collection persister
0739:             */
0740:            private void addCollection(PersistentCollection collection,
0741:                    CollectionPersister persister) {
0742:                CollectionEntry ce = new CollectionEntry(persister, collection);
0743:                collectionEntries.put(collection, ce);
0744:            }
0745:
0746:            /**
0747:             * add an (initialized) collection that was created by another session and passed
0748:             * into update() (ie. one with a snapshot and existing state on the database)
0749:             */
0750:            public void addInitializedDetachedCollection(
0751:                    CollectionPersister collectionPersister,
0752:                    PersistentCollection collection) throws HibernateException {
0753:                if (collection.isUnreferenced()) {
0754:                    //treat it just like a new collection
0755:                    addCollection(collection, collectionPersister);
0756:                } else {
0757:                    CollectionEntry ce = new CollectionEntry(collection,
0758:                            session.getFactory());
0759:                    addCollection(collection, ce, collection.getKey());
0760:                }
0761:            }
0762:
0763:            /**
0764:             * add a collection we just pulled out of the cache (does not need initializing)
0765:             */
0766:            public CollectionEntry addInitializedCollection(
0767:                    CollectionPersister persister,
0768:                    PersistentCollection collection, Serializable id)
0769:                    throws HibernateException {
0770:                CollectionEntry ce = new CollectionEntry(collection, persister,
0771:                        id, flushing);
0772:                ce.postInitialize(collection);
0773:                addCollection(collection, ce, id);
0774:                return ce;
0775:            }
0776:
0777:            /**
0778:             * Get the collection instance associated with the <tt>CollectionKey</tt>
0779:             */
0780:            public PersistentCollection getCollection(
0781:                    CollectionKey collectionKey) {
0782:                return (PersistentCollection) collectionsByKey
0783:                        .get(collectionKey);
0784:            }
0785:
0786:            /**
0787:             * Register a collection for non-lazy loading at the end of the
0788:             * two-phase load
0789:             */
0790:            public void addNonLazyCollection(PersistentCollection collection) {
0791:                nonlazyCollections.add(collection);
0792:            }
0793:
0794:            /**
0795:             * Force initialization of all non-lazy collections encountered during
0796:             * the current two-phase load (actually, this is a no-op, unless this
0797:             * is the "outermost" load)
0798:             */
0799:            public void initializeNonLazyCollections()
0800:                    throws HibernateException {
0801:                if (loadCounter == 0) {
0802:                    log.debug("initializing non-lazy collections");
0803:                    //do this work only at the very highest level of the load
0804:                    loadCounter++; //don't let this method be called recursively
0805:                    try {
0806:                        int size;
0807:                        while ((size = nonlazyCollections.size()) > 0) {
0808:                            //note that each iteration of the loop may add new elements
0809:                            ((PersistentCollection) nonlazyCollections
0810:                                    .remove(size - 1)).forceInitialization();
0811:                        }
0812:                    } finally {
0813:                        loadCounter--;
0814:                        clearNullProperties();
0815:                    }
0816:                }
0817:            }
0818:
0819:            /**
0820:             * Get the <tt>PersistentCollection</tt> object for an array
0821:             */
0822:            public PersistentCollection getCollectionHolder(Object array) {
0823:                return (PersistentCollection) arrayHolders.get(array);
0824:            }
0825:
0826:            /**
0827:             * Register a <tt>PersistentCollection</tt> object for an array.
0828:             * Associates a holder with an array - MUST be called after loading 
0829:             * array, since the array instance is not created until endLoad().
0830:             */
0831:            public void addCollectionHolder(PersistentCollection holder) {
0832:                //TODO:refactor + make this method private
0833:                arrayHolders.put(holder.getValue(), holder);
0834:            }
0835:
0836:            public PersistentCollection removeCollectionHolder(Object array) {
0837:                return (PersistentCollection) arrayHolders.remove(array);
0838:            }
0839:
0840:            /**
0841:             * Get the snapshot of the pre-flush collection state
0842:             */
0843:            public Serializable getSnapshot(PersistentCollection coll) {
0844:                return getCollectionEntry(coll).getSnapshot();
0845:            }
0846:
0847:            /**
0848:             * Get the collection entry for a collection passed to filter,
0849:             * which might be a collection wrapper, an array, or an unwrapped
0850:             * collection. Return null if there is no entry.
0851:             */
0852:            public CollectionEntry getCollectionEntryOrNull(Object collection) {
0853:                PersistentCollection coll;
0854:                if (collection instanceof  PersistentCollection) {
0855:                    coll = (PersistentCollection) collection;
0856:                    //if (collection==null) throw new TransientObjectException("Collection was not yet persistent");
0857:                } else {
0858:                    coll = getCollectionHolder(collection);
0859:                    if (coll == null) {
0860:                        //it might be an unwrapped collection reference!
0861:                        //try to find a wrapper (slowish)
0862:                        Iterator wrappers = IdentityMap
0863:                                .keyIterator(collectionEntries);
0864:                        while (wrappers.hasNext()) {
0865:                            PersistentCollection pc = (PersistentCollection) wrappers
0866:                                    .next();
0867:                            if (pc.isWrapper(collection)) {
0868:                                coll = pc;
0869:                                break;
0870:                            }
0871:                        }
0872:                    }
0873:                }
0874:
0875:                return (coll == null) ? null : getCollectionEntry(coll);
0876:            }
0877:
0878:            /**
0879:             * Get an existing proxy by key
0880:             */
0881:            public Object getProxy(EntityKey key) {
0882:                return proxiesByKey.get(key);
0883:            }
0884:
0885:            /**
0886:             * Add a proxy to the session cache
0887:             */
0888:            public void addProxy(EntityKey key, Object proxy) {
0889:                proxiesByKey.put(key, proxy);
0890:            }
0891:
0892:            /**
0893:             * Remove a proxy from the session cache.
0894:             * <p/>
0895:             * Additionally, ensure that any load optimization references
0896:             * such as batch or subselect loading get cleaned up as well.
0897:             *
0898:             * @param key The key of the entity proxy to be removed
0899:             * @return The proxy reference.
0900:             */
0901:            public Object removeProxy(EntityKey key) {
0902:                if (batchFetchQueue != null) {
0903:                    batchFetchQueue.removeBatchLoadableEntityKey(key);
0904:                    batchFetchQueue.removeSubselect(key);
0905:                }
0906:                return proxiesByKey.remove(key);
0907:            }
0908:
0909:            /**
0910:             * Record the fact that an entity does not exist in the database
0911:             * 
0912:             * @param key the primary key of the entity
0913:             */
0914:            /*public void addNonExistantEntityKey(EntityKey key) {
0915:            	nonExistantEntityKeys.add(key);
0916:            }*/
0917:
0918:            /**
0919:             * Record the fact that an entity does not exist in the database
0920:             * 
0921:             * @param key a unique key of the entity
0922:             */
0923:            /*public void addNonExistantEntityUniqueKey(EntityUniqueKey key) {
0924:            	nonExistentEntityUniqueKeys.add(key);
0925:            }*/
0926:
0927:            /*public void removeNonExist(EntityKey key) {
0928:            	nonExistantEntityKeys.remove(key);
0929:            }*/
0930:
0931:            /** 
0932:             * Retrieve the set of EntityKeys representing nullifiable references
0933:             */
0934:            public HashSet getNullifiableEntityKeys() {
0935:                return nullifiableEntityKeys;
0936:            }
0937:
0938:            public Map getEntitiesByKey() {
0939:                return entitiesByKey;
0940:            }
0941:
0942:            public Map getEntityEntries() {
0943:                return entityEntries;
0944:            }
0945:
0946:            public Map getCollectionEntries() {
0947:                return collectionEntries;
0948:            }
0949:
0950:            public Map getCollectionsByKey() {
0951:                return collectionsByKey;
0952:            }
0953:
0954:            /**
0955:             * Do we already know that the entity does not exist in the
0956:             * database?
0957:             */
0958:            /*public boolean isNonExistant(EntityKey key) {
0959:            	return nonExistantEntityKeys.contains(key);
0960:            }*/
0961:
0962:            /**
0963:             * Do we already know that the entity does not exist in the
0964:             * database?
0965:             */
0966:            /*public boolean isNonExistant(EntityUniqueKey key) {
0967:            	return nonExistentEntityUniqueKeys.contains(key);
0968:            }*/
0969:
0970:            public int getCascadeLevel() {
0971:                return cascading;
0972:            }
0973:
0974:            public int incrementCascadeLevel() {
0975:                return ++cascading;
0976:            }
0977:
0978:            public int decrementCascadeLevel() {
0979:                return --cascading;
0980:            }
0981:
0982:            public boolean isFlushing() {
0983:                return flushing;
0984:            }
0985:
0986:            public void setFlushing(boolean flushing) {
0987:                this .flushing = flushing;
0988:            }
0989:
0990:            /**
0991:             * Call this before begining a two-phase load
0992:             */
0993:            public void beforeLoad() {
0994:                loadCounter++;
0995:            }
0996:
0997:            /**
0998:             * Call this after finishing a two-phase load
0999:             */
1000:            public void afterLoad() {
1001:                loadCounter--;
1002:            }
1003:
1004:            /**
1005:             * Returns a string representation of the object.
1006:             *
1007:             * @return a string representation of the object.
1008:             */
1009:            public String toString() {
1010:                return new StringBuffer().append(
1011:                        "PersistenceContext[entityKeys=").append(
1012:                        entitiesByKey.keySet()).append(",collectionKeys=")
1013:                        .append(collectionsByKey.keySet()).append("]")
1014:                        .toString();
1015:            }
1016:
1017:            /**
1018:             * Search the persistence context for an owner for the child object,
1019:             * given a collection role. If <tt>mergeMap</tt> is non-null, also
1020:             * check the detached graph being merged for a parent.
1021:             */
1022:            public Serializable getOwnerId(String entity, String property,
1023:                    Object childEntity, Map mergeMap) {
1024:
1025:                EntityPersister persister = session.getFactory()
1026:                        .getEntityPersister(entity);
1027:                final CollectionPersister collectionPersister = session
1028:                        .getFactory().getCollectionPersister(
1029:                                entity + '.' + property);
1030:
1031:                Iterator entities = entityEntries.entrySet().iterator();
1032:                while (entities.hasNext()) {
1033:                    Map.Entry me = (Map.Entry) entities.next();
1034:                    EntityEntry ee = (EntityEntry) me.getValue();
1035:                    if (persister.isSubclassEntityName(ee.getEntityName())) {
1036:                        Object instance = me.getKey();
1037:
1038:                        //check if the managed object is the parent
1039:                        boolean found = isFoundInParent(property, childEntity,
1040:                                persister, collectionPersister, instance);
1041:
1042:                        if (!found && mergeMap != null) {
1043:                            //check if the detached object being merged is the parent
1044:                            Object unmergedInstance = mergeMap.get(instance);
1045:                            Object unmergedChild = mergeMap.get(childEntity);
1046:                            if (unmergedInstance != null
1047:                                    && unmergedChild != null) {
1048:                                found = isFoundInParent(property,
1049:                                        unmergedChild, persister,
1050:                                        collectionPersister, unmergedInstance);
1051:                            }
1052:                        }
1053:
1054:                        if (found) {
1055:                            return ee.getId();
1056:                        }
1057:
1058:                    }
1059:                }
1060:                return null;
1061:            }
1062:
1063:            private boolean isFoundInParent(String property,
1064:                    Object childEntity, EntityPersister persister,
1065:                    CollectionPersister collectionPersister,
1066:                    Object potentialParent) {
1067:                Object collection = persister.getPropertyValue(potentialParent,
1068:                        property, session.getEntityMode());
1069:                return collection != null
1070:                        && Hibernate.isInitialized(collection)
1071:                        && collectionPersister.getCollectionType().contains(
1072:                                collection, childEntity, session);
1073:            }
1074:
1075:            /**
1076:             * Search the persistence context for an index of the child object,
1077:             * given a collection role
1078:             */
1079:            public Object getIndexInOwner(String entity, String property,
1080:                    Object childEntity, Map mergeMap) {
1081:
1082:                EntityPersister persister = session.getFactory()
1083:                        .getEntityPersister(entity);
1084:                CollectionPersister cp = session.getFactory()
1085:                        .getCollectionPersister(entity + '.' + property);
1086:                Iterator entities = entityEntries.entrySet().iterator();
1087:                while (entities.hasNext()) {
1088:                    Map.Entry me = (Map.Entry) entities.next();
1089:                    EntityEntry ee = (EntityEntry) me.getValue();
1090:                    if (persister.isSubclassEntityName(ee.getEntityName())) {
1091:                        Object instance = me.getKey();
1092:
1093:                        Object index = getIndexInParent(property, childEntity,
1094:                                persister, cp, instance);
1095:
1096:                        if (index == null && mergeMap != null) {
1097:                            Object unmergedInstance = mergeMap.get(instance);
1098:                            Object unmergedChild = mergeMap.get(childEntity);
1099:                            if (unmergedInstance != null
1100:                                    && unmergedChild != null) {
1101:                                index = getIndexInParent(property,
1102:                                        unmergedChild, persister, cp,
1103:                                        unmergedInstance);
1104:                            }
1105:                        }
1106:
1107:                        if (index != null)
1108:                            return index;
1109:                    }
1110:                }
1111:                return null;
1112:            }
1113:
1114:            private Object getIndexInParent(String property,
1115:                    Object childEntity, EntityPersister persister,
1116:                    CollectionPersister collectionPersister,
1117:                    Object potentialParent) {
1118:                Object collection = persister.getPropertyValue(potentialParent,
1119:                        property, session.getEntityMode());
1120:                if (collection != null && Hibernate.isInitialized(collection)) {
1121:                    return collectionPersister.getCollectionType().indexOf(
1122:                            collection, childEntity);
1123:                } else {
1124:                    return null;
1125:                }
1126:            }
1127:
1128:            /**
1129:             * Record the fact that the association belonging to the keyed
1130:             * entity is null.
1131:             */
1132:            public void addNullProperty(EntityKey ownerKey, String propertyName) {
1133:                nullAssociations
1134:                        .add(new AssociationKey(ownerKey, propertyName));
1135:            }
1136:
1137:            /**
1138:             * Is the association property belonging to the keyed entity null?
1139:             */
1140:            public boolean isPropertyNull(EntityKey ownerKey,
1141:                    String propertyName) {
1142:                return nullAssociations.contains(new AssociationKey(ownerKey,
1143:                        propertyName));
1144:            }
1145:
1146:            private void clearNullProperties() {
1147:                nullAssociations.clear();
1148:            }
1149:
1150:            public void setReadOnly(Object entity, boolean readOnly) {
1151:                EntityEntry entry = getEntry(entity);
1152:                if (entry == null) {
1153:                    throw new TransientObjectException(
1154:                            "Instance was not associated with the session");
1155:                }
1156:                entry.setReadOnly(readOnly, entity);
1157:                hasNonReadOnlyEntities = hasNonReadOnlyEntities || !readOnly;
1158:            }
1159:
1160:            public void replaceDelayedEntityIdentityInsertKeys(
1161:                    EntityKey oldKey, Serializable generatedId) {
1162:                Object entity = entitiesByKey.remove(oldKey);
1163:                EntityEntry oldEntry = (EntityEntry) entityEntries
1164:                        .remove(entity);
1165:
1166:                EntityKey newKey = new EntityKey(generatedId, oldEntry
1167:                        .getPersister(), getSession().getEntityMode());
1168:                addEntity(newKey, entity);
1169:                addEntry(entity, oldEntry.getStatus(), oldEntry
1170:                        .getLoadedState(), oldEntry.getRowId(), generatedId,
1171:                        oldEntry.getVersion(), oldEntry.getLockMode(), oldEntry
1172:                                .isExistsInDatabase(), oldEntry.getPersister(),
1173:                        oldEntry.isBeingReplicated(), oldEntry
1174:                                .isLoadedWithLazyPropertiesUnfetched());
1175:            }
1176:
1177:            /**
1178:             * Used by the owning session to explicitly control serialization of the
1179:             * persistence context.
1180:             *
1181:             * @param oos The stream to which the persistence context should get written
1182:             * @throws IOException serialization errors.
1183:             */
1184:            public void serialize(ObjectOutputStream oos) throws IOException {
1185:                log.trace("serializing persistent-context");
1186:
1187:                oos.writeBoolean(hasNonReadOnlyEntities);
1188:
1189:                oos.writeInt(entitiesByKey.size());
1190:                log.trace("starting serialization of [" + entitiesByKey.size()
1191:                        + "] entitiesByKey entries");
1192:                Iterator itr = entitiesByKey.entrySet().iterator();
1193:                while (itr.hasNext()) {
1194:                    Map.Entry entry = (Map.Entry) itr.next();
1195:                    ((EntityKey) entry.getKey()).serialize(oos);
1196:                    oos.writeObject(entry.getValue());
1197:                }
1198:
1199:                oos.writeInt(entitiesByUniqueKey.size());
1200:                log.trace("starting serialization of ["
1201:                        + entitiesByUniqueKey.size()
1202:                        + "] entitiesByUniqueKey entries");
1203:                itr = entitiesByUniqueKey.entrySet().iterator();
1204:                while (itr.hasNext()) {
1205:                    Map.Entry entry = (Map.Entry) itr.next();
1206:                    ((EntityUniqueKey) entry.getKey()).serialize(oos);
1207:                    oos.writeObject(entry.getValue());
1208:                }
1209:
1210:                oos.writeInt(proxiesByKey.size());
1211:                log.trace("starting serialization of [" + proxiesByKey.size()
1212:                        + "] proxiesByKey entries");
1213:                itr = proxiesByKey.entrySet().iterator();
1214:                while (itr.hasNext()) {
1215:                    Map.Entry entry = (Map.Entry) itr.next();
1216:                    ((EntityKey) entry.getKey()).serialize(oos);
1217:                    oos.writeObject(entry.getValue());
1218:                }
1219:
1220:                oos.writeInt(entitySnapshotsByKey.size());
1221:                log.trace("starting serialization of ["
1222:                        + entitySnapshotsByKey.size()
1223:                        + "] entitySnapshotsByKey entries");
1224:                itr = entitySnapshotsByKey.entrySet().iterator();
1225:                while (itr.hasNext()) {
1226:                    Map.Entry entry = (Map.Entry) itr.next();
1227:                    ((EntityKey) entry.getKey()).serialize(oos);
1228:                    oos.writeObject(entry.getValue());
1229:                }
1230:
1231:                oos.writeInt(entityEntries.size());
1232:                log.trace("starting serialization of [" + entityEntries.size()
1233:                        + "] entityEntries entries");
1234:                itr = entityEntries.entrySet().iterator();
1235:                while (itr.hasNext()) {
1236:                    Map.Entry entry = (Map.Entry) itr.next();
1237:                    oos.writeObject(entry.getKey());
1238:                    ((EntityEntry) entry.getValue()).serialize(oos);
1239:                }
1240:
1241:                oos.writeInt(collectionsByKey.size());
1242:                log.trace("starting serialization of ["
1243:                        + collectionsByKey.size()
1244:                        + "] collectionsByKey entries");
1245:                itr = collectionsByKey.entrySet().iterator();
1246:                while (itr.hasNext()) {
1247:                    Map.Entry entry = (Map.Entry) itr.next();
1248:                    ((CollectionKey) entry.getKey()).serialize(oos);
1249:                    oos.writeObject(entry.getValue());
1250:                }
1251:
1252:                oos.writeInt(collectionEntries.size());
1253:                log.trace("starting serialization of ["
1254:                        + collectionEntries.size()
1255:                        + "] collectionEntries entries");
1256:                itr = collectionEntries.entrySet().iterator();
1257:                while (itr.hasNext()) {
1258:                    Map.Entry entry = (Map.Entry) itr.next();
1259:                    oos.writeObject(entry.getKey());
1260:                    ((CollectionEntry) entry.getValue()).serialize(oos);
1261:                }
1262:
1263:                oos.writeInt(arrayHolders.size());
1264:                log.trace("starting serialization of [" + arrayHolders.size()
1265:                        + "] arrayHolders entries");
1266:                itr = arrayHolders.entrySet().iterator();
1267:                while (itr.hasNext()) {
1268:                    Map.Entry entry = (Map.Entry) itr.next();
1269:                    oos.writeObject(entry.getKey());
1270:                    oos.writeObject(entry.getValue());
1271:                }
1272:
1273:                oos.writeInt(nullifiableEntityKeys.size());
1274:                log.trace("starting serialization of ["
1275:                        + nullifiableEntityKeys.size()
1276:                        + "] nullifiableEntityKeys entries");
1277:                itr = nullifiableEntityKeys.iterator();
1278:                while (itr.hasNext()) {
1279:                    EntityKey entry = (EntityKey) itr.next();
1280:                    entry.serialize(oos);
1281:                }
1282:            }
1283:
1284:            public static StatefulPersistenceContext deserialize(
1285:                    ObjectInputStream ois, SessionImplementor session)
1286:                    throws IOException, ClassNotFoundException {
1287:                log.trace("deserializing persistent-context");
1288:                StatefulPersistenceContext rtn = new StatefulPersistenceContext(
1289:                        session);
1290:
1291:                // during deserialization, we need to reconnect all proxies and
1292:                // collections to this session, as well as the EntityEntry and
1293:                // CollectionEntry instances; these associations are transient
1294:                // because serialization is used for different things.
1295:
1296:                try {
1297:                    // todo : we can actually just determine this from the incoming EntityEntry-s
1298:                    rtn.hasNonReadOnlyEntities = ois.readBoolean();
1299:
1300:                    int count = ois.readInt();
1301:                    log.trace("staring deserialization of [" + count
1302:                            + "] entitiesByKey entries");
1303:                    rtn.entitiesByKey = new HashMap(
1304:                            count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
1305:                    for (int i = 0; i < count; i++) {
1306:                        rtn.entitiesByKey.put(EntityKey.deserialize(ois,
1307:                                session), ois.readObject());
1308:                    }
1309:
1310:                    count = ois.readInt();
1311:                    log.trace("staring deserialization of [" + count
1312:                            + "] entitiesByUniqueKey entries");
1313:                    rtn.entitiesByUniqueKey = new HashMap(
1314:                            count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
1315:                    for (int i = 0; i < count; i++) {
1316:                        rtn.entitiesByUniqueKey.put(EntityUniqueKey
1317:                                .deserialize(ois, session), ois.readObject());
1318:                    }
1319:
1320:                    count = ois.readInt();
1321:                    log.trace("staring deserialization of [" + count
1322:                            + "] proxiesByKey entries");
1323:                    rtn.proxiesByKey = new ReferenceMap(ReferenceMap.HARD,
1324:                            ReferenceMap.WEAK,
1325:                            count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count,
1326:                            .75f);
1327:                    for (int i = 0; i < count; i++) {
1328:                        EntityKey ek = EntityKey.deserialize(ois, session);
1329:                        Object proxy = ois.readObject();
1330:                        if (proxy instanceof  HibernateProxy) {
1331:                            ((HibernateProxy) proxy)
1332:                                    .getHibernateLazyInitializer().setSession(
1333:                                            session);
1334:                            rtn.proxiesByKey.put(ek, proxy);
1335:                        } else {
1336:                            log.trace("encountered prunded proxy");
1337:                        }
1338:                        // otherwise, the proxy was pruned during the serialization process
1339:                    }
1340:
1341:                    count = ois.readInt();
1342:                    log.trace("staring deserialization of [" + count
1343:                            + "] entitySnapshotsByKey entries");
1344:                    rtn.entitySnapshotsByKey = new HashMap(
1345:                            count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
1346:                    for (int i = 0; i < count; i++) {
1347:                        rtn.entitySnapshotsByKey.put(EntityKey.deserialize(ois,
1348:                                session), ois.readObject());
1349:                    }
1350:
1351:                    count = ois.readInt();
1352:                    log.trace("staring deserialization of [" + count
1353:                            + "] entityEntries entries");
1354:                    rtn.entityEntries = IdentityMap
1355:                            .instantiateSequenced(count < INIT_COLL_SIZE ? INIT_COLL_SIZE
1356:                                    : count);
1357:                    for (int i = 0; i < count; i++) {
1358:                        Object entity = ois.readObject();
1359:                        EntityEntry entry = EntityEntry.deserialize(ois,
1360:                                session);
1361:                        rtn.entityEntries.put(entity, entry);
1362:                    }
1363:
1364:                    count = ois.readInt();
1365:                    log.trace("staring deserialization of [" + count
1366:                            + "] collectionsByKey entries");
1367:                    rtn.collectionsByKey = new HashMap(
1368:                            count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
1369:                    for (int i = 0; i < count; i++) {
1370:                        rtn.collectionsByKey.put(CollectionKey.deserialize(ois,
1371:                                session), ois.readObject());
1372:                    }
1373:
1374:                    count = ois.readInt();
1375:                    log.trace("staring deserialization of [" + count
1376:                            + "] collectionEntries entries");
1377:                    rtn.collectionEntries = IdentityMap
1378:                            .instantiateSequenced(count < INIT_COLL_SIZE ? INIT_COLL_SIZE
1379:                                    : count);
1380:                    for (int i = 0; i < count; i++) {
1381:                        final PersistentCollection pc = (PersistentCollection) ois
1382:                                .readObject();
1383:                        final CollectionEntry ce = CollectionEntry.deserialize(
1384:                                ois, session);
1385:                        pc.setCurrentSession(session);
1386:                        rtn.collectionEntries.put(pc, ce);
1387:                    }
1388:
1389:                    count = ois.readInt();
1390:                    log.trace("staring deserialization of [" + count
1391:                            + "] arrayHolders entries");
1392:                    rtn.arrayHolders = IdentityMap
1393:                            .instantiate(count < INIT_COLL_SIZE ? INIT_COLL_SIZE
1394:                                    : count);
1395:                    for (int i = 0; i < count; i++) {
1396:                        rtn.arrayHolders
1397:                                .put(ois.readObject(), ois.readObject());
1398:                    }
1399:
1400:                    count = ois.readInt();
1401:                    log.trace("staring deserialization of [" + count
1402:                            + "] nullifiableEntityKeys entries");
1403:                    rtn.nullifiableEntityKeys = new HashSet();
1404:                    for (int i = 0; i < count; i++) {
1405:                        rtn.nullifiableEntityKeys.add(EntityKey.deserialize(
1406:                                ois, session));
1407:                    }
1408:
1409:                } catch (HibernateException he) {
1410:                    throw new InvalidObjectException(he.getMessage());
1411:                }
1412:
1413:                return rtn;
1414:            }
1415:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.