Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/impl In directory sc8-pr-cvs1:/tmp/cvs-serv24602/hibernate/impl Modified Files: IteratorImpl.java ScheduledCollectionUpdate.java SessionFactoryImpl.java SessionFactoryObjectFactory.java SessionImpl.java Log Message: * SessionFactory.close() now unbinds from JNDI * added Session.remove() * got rid of another unnecessry collection delete() Index: IteratorImpl.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/impl/IteratorImpl.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** IteratorImpl.java 5 Jan 2003 02:11:21 -0000 1.3 --- IteratorImpl.java 19 Apr 2003 03:26:07 -0000 1.4 *************** *** 44,51 **** --- 44,53 ---- this.hasNext = hasNext; if (!hasNext) { + log.debug("exhausted results"); nextResults = null; rs.close(); } else { + log.debug("retrieving next results"); nextResults = new Object[types.length]; for (int i=0; i<types.length; i++) { *************** *** 64,67 **** --- 66,70 ---- currentResults = nextResults; postNext( rs.next() ); + log.debug("returning current results"); if (single) { return currentResults[0]; Index: ScheduledCollectionUpdate.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/impl/ScheduledCollectionUpdate.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ScheduledCollectionUpdate.java 2 Apr 2003 01:06:51 -0000 1.6 --- ScheduledCollectionUpdate.java 19 Apr 2003 03:26:07 -0000 1.7 *************** *** 14,21 **** private final PersistentCollection collection; ! public ScheduledCollectionUpdate(PersistentCollection collection, CollectionPersister persister, Serializable id, SessionImplementor session) { super(persister, id, session); this.collection = collection; } --- 14,28 ---- private final PersistentCollection collection; + private final boolean emptySnapshot; ! public ScheduledCollectionUpdate( ! PersistentCollection collection, ! CollectionPersister persister, ! Serializable id, ! boolean emptySnapshot, ! SessionImplementor session) { super(persister, id, session); this.collection = collection; + this.emptySnapshot = emptySnapshot; } *************** *** 27,34 **** } else if ( collection.empty() ) { ! persister.remove(id, session); } ! else if ( collection.needsRecreate( persister.getElementType() ) ) { ! persister.remove(id, session); persister.recreate(collection, id, session); } --- 34,41 ---- } else if ( collection.empty() ) { ! if (!emptySnapshot) persister.remove(id, session); } ! else if ( collection.needsRecreate() ) { ! if (!emptySnapshot) persister.remove(id, session); persister.recreate(collection, id, session); } Index: SessionFactoryImpl.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/impl/SessionFactoryImpl.java,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** SessionFactoryImpl.java 10 Apr 2003 09:49:16 -0000 1.18 --- SessionFactoryImpl.java 19 Apr 2003 03:26:07 -0000 1.19 *************** *** 120,123 **** --- 120,125 ---- public SessionFactoryImpl(Configuration cfg, Properties properties, Interceptor interceptor) throws HibernateException { + log.info("building session factory"); + if ( log.isDebugEnabled() ) log.debug("instantiating session factory with properties: " + properties); *************** *** 283,288 **** imports = new HashMap( cfg.getImports() ); ! ! log.debug("Instantiated session factory"); } --- 285,289 ---- imports = new HashMap( cfg.getImports() ); ! log.debug("instantiated session factory"); } *************** *** 703,708 **** public void close() throws HibernateException { if (statementCache!=null) statementCache.close(); ! connections.close(); } --- 704,717 ---- public void close() throws HibernateException { + + log.info("closing"); + if (statementCache!=null) statementCache.close(); ! try { ! connections.close(); ! } ! finally { ! SessionFactoryObjectFactory.removeInstance(uuid, name, properties); ! } } Index: SessionFactoryObjectFactory.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/impl/SessionFactoryObjectFactory.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** SessionFactoryObjectFactory.java 5 Jan 2003 02:11:21 -0000 1.3 --- SessionFactoryObjectFactory.java 19 Apr 2003 03:26:07 -0000 1.4 *************** *** 106,109 **** --- 106,135 ---- } + public static void removeInstance(String uid, String name, Properties properties) { + //TODO: theoretically non-threadsafe... + + if (name!=null) { + log.info("Unbinding factory: " + name); + + try { + Context ctx = NamingHelper.getInitialContext(properties); + ctx.unbind(name); + log.info("Unbound factory from JNDI name: " + name); + } + catch (InvalidNameException ine) { + log.error("Invalid JNDI name: " + name, ine); + } + catch (NamingException ne) { + log.warn("Could not unbind factory from JNDI", ne); + } + + namedInstances.remove(name); + + } + + instances.remove(uid); + + } + public static Object getNamedInstance(String name) { log.debug("lookup: name=" + name); *************** *** 125,140 **** return result; } ! ! /** ! * Theoretically nonthreadsafe, but its only called by ! * applications using <tt>Hibernate.configure()</tt> which ! * is synchronized, so it shouldn't be a problem in ! * practice. ! */ ! public static void clear() { ! instances.clear(); ! namedInstances.clear(); ! } ! } --- 151,155 ---- return result; } ! } Index: SessionImpl.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/impl/SessionImpl.java,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** SessionImpl.java 16 Apr 2003 04:54:32 -0000 1.35 --- SessionImpl.java 19 Apr 2003 03:26:07 -0000 1.36 *************** *** 648,652 **** } ! if ( log.isTraceEnabled() ) log.trace( "saving " + infoString(persister,id) ); if (!identityCol) { // if the id is generated by the database, we assign the key later --- 648,652 ---- } ! if ( log.isTraceEnabled() ) log.trace( "saving " + infoString(persister, id) ); if (!identityCol) { // if the id is generated by the database, we assign the key later *************** *** 1035,1038 **** --- 1035,1039 ---- private void removeCollection(CollectionPersister role, Serializable id) { + if ( log.isTraceEnabled() ) log.trace( "collection dereferenced while transient " + infoString(role, id) ); collectionRemovals.add( new ScheduledCollectionRemove(role, id, false, this) ); } *************** *** 1045,1051 **** PersistentCollection coll = (PersistentCollection) value; if ( coll.wasInitialized() ) { ! CollectionSnapshot cs = coll.getCollectionSnapshot(); ! if (cs!=null && cs.getRole().equals( persister.getRole() ) && cs.getKey().equals(id) ) { ! if ( coll.setSession(this) ) addInitializedCollection(coll, cs); } else { --- 1046,1056 ---- PersistentCollection coll = (PersistentCollection) value; if ( coll.wasInitialized() ) { ! CollectionSnapshot snapshot = coll.getCollectionSnapshot(); ! if ( ! snapshot!=null && ! snapshot.getRole().equals( persister.getRole() ) && ! snapshot.getKey().equals(id) ! ) { ! if ( coll.setSession(this) ) addInitializedCollection(coll, snapshot); } else { *************** *** 1790,1793 **** --- 1795,1799 ---- } lock(old, lockMode); + if ( log.isTraceEnabled() ) log.trace( "resolved object in session cache " + infoString(persister, id) ); return old; } *************** *** 1798,1806 **** CacheEntry entry = persister.hasCache() ? (CacheEntry) persister.getCache().get(id, timestamp) : null; if (entry!=null) { ClassPersister subclassPersister = getPersister( entry.getSubclass() ); Object result = (isOptionalObject) ? optionalObject : instantiate(subclassPersister, id); addEntry(result, LOADING, null, id, null, LockMode.NONE, true, subclassPersister); //make it circular-reference safe addEntity( new Key(id, persister), result ); ! Object[] values = entry.assemble(result, id, subclassPersister, this); // intializes cached by side-effect Type[] types = subclassPersister.getPropertyTypes(); TypeFactory.deepCopy(values, types, subclassPersister.getPropertyUpdateability(), values); --- 1804,1813 ---- CacheEntry entry = persister.hasCache() ? (CacheEntry) persister.getCache().get(id, timestamp) : null; if (entry!=null) { + if ( log.isTraceEnabled() ) log.trace( "resolved object in JCS cache " + infoString(persister, id) ); ClassPersister subclassPersister = getPersister( entry.getSubclass() ); Object result = (isOptionalObject) ? optionalObject : instantiate(subclassPersister, id); addEntry(result, LOADING, null, id, null, LockMode.NONE, true, subclassPersister); //make it circular-reference safe addEntity( new Key(id, persister), result ); ! Object[] values = entry.assemble(result, id, subclassPersister, this); // intializes result by side-effect Type[] types = subclassPersister.getPropertyTypes(); TypeFactory.deepCopy(values, types, subclassPersister.getPropertyUpdateability(), values); *************** *** 1817,1821 **** else { //otherwise go ahead and load it! ! // Note: you can't use "for update" with an outer join try { return persister.load(id, optionalObject, lockMode, this); --- 1824,1828 ---- else { //otherwise go ahead and load it! ! if ( log.isTraceEnabled() ) log.trace( "object not resolved in any cache " + infoString(persister, id) ); try { return persister.load(id, optionalObject, lockMode, this); *************** *** 1846,1849 **** --- 1853,1858 ---- EntityEntry e = removeEntry(object); + if ( log.isTraceEnabled() ) log.trace( "refreshing " + infoString(e.persister, e.id) ); + if ( !e.existsInDatabase ) throw new HibernateException("this instance does not yet exist as a row in the database"); *************** *** 1867,1871 **** Type[] types = persister.getPropertyTypes(); ! if ( log.isDebugEnabled() ) log.debug( "resolving associations for: " + infoString(persister, id) ); interceptor.onLoad( object, id, hydratedState, persister.getPropertyNames(), types ); --- 1876,1880 ---- Type[] types = persister.getPropertyTypes(); ! if ( log.isDebugEnabled() ) log.debug( "resolving associations for " + infoString(persister, id) ); interceptor.onLoad( object, id, hydratedState, persister.getPropertyNames(), types ); *************** *** 1877,1882 **** TypeFactory.deepCopy(hydratedState, persister.getPropertyTypes(), persister.getPropertyUpdateability(), hydratedState); //after setting values to object ! if ( persister.hasCache() ) ! persister.getCache().put( id, new CacheEntry(object, persister, this), timestamp ); reentrantCallback=true; --- 1886,1893 ---- TypeFactory.deepCopy(hydratedState, persister.getPropertyTypes(), persister.getPropertyUpdateability(), hydratedState); //after setting values to object ! if ( persister.hasCache() ) { ! if ( log.isDebugEnabled() ) log.debug( "adding entity to JCS cache " + infoString(persister, id) ); ! persister.getCache().put( id, new CacheEntry(object, persister, this), timestamp ); ! } reentrantCallback=true; *************** *** 1886,1889 **** --- 1897,1902 ---- reentrantCallback=false; + if ( log.isDebugEnabled() ) log.debug( "done materializing entity " + infoString(persister, id) ); + } *************** *** 1967,1971 **** private void execute() throws HibernateException { ! log.trace("Executing"); try { --- 1980,1984 ---- private void execute() throws HibernateException { ! log.trace("executing flush"); try { *************** *** 2273,2277 **** if ( ce.dorecreate ) collectionCreations.add( new ScheduledCollectionRecreate(coll, ce.currentPersister, ce.currentKey, this) ); if ( ce.doremove ) collectionRemovals.add( new ScheduledCollectionRemove(ce.loadedPersister, ce.loadedKey, ce.snapshotIsEmpty(), this) ); ! if ( ce.doupdate ) collectionUpdates.add( new ScheduledCollectionUpdate(coll, ce.loadedPersister, ce.loadedKey, this) ); } --- 2286,2290 ---- if ( ce.dorecreate ) collectionCreations.add( new ScheduledCollectionRecreate(coll, ce.currentPersister, ce.currentKey, this) ); if ( ce.doremove ) collectionRemovals.add( new ScheduledCollectionRemove(ce.loadedPersister, ce.loadedKey, ce.snapshotIsEmpty(), this) ); ! if ( ce.doupdate ) collectionUpdates.add( new ScheduledCollectionUpdate(coll, ce.loadedPersister, ce.loadedKey, ce.snapshotIsEmpty(), this) ); } *************** *** 2983,2986 **** --- 2996,3057 ---- else { return entries.containsKey(object); + } + } + + public void remove(Object object) throws HibernateException { + if (object instanceof HibernateProxy) { + LazyInitializer li = HibernateProxyHelper.getLazyInitializer( (HibernateProxy) object ); + Serializable id = li.getIdentifier(); + ClassPersister persister = getPersister( li.getPersistentClass() ); + Key key = new Key(id, persister); + proxiesByKey.remove(key); + if ( !li.isUninitialized() ) { + Object entity = removeEntity(key); + if (entity!=null) { + removeEntry(entity); + doRemove(persister, entity); + } + } + } + else { + EntityEntry e = (EntityEntry) removeEntry(object); + if (e!=null) { + removeEntity( new Key(e.id, e.persister) ); + doRemove(e.persister, object); + } + } + } + + private void doRemove(ClassPersister persister, Object object) throws HibernateException { + + if ( log.isTraceEnabled() ) log.trace( "removing from session cache " + infoString(persister) ); + + //remove all collections for the entity + disassociateCollections( persister.getPropertyValues(object), persister.getPropertyTypes() ); + Cascades.cascade(this, persister, object, Cascades.ACTION_REMOVE, Cascades.CASCADE_ON_REMOVE); + } + + private void disassociateCollections(Object[] values, Type[] types) throws HibernateException { + for ( int i=0; i<types.length; i++ ) { + if ( types[i].isPersistentCollectionType() ) { + Object pc=null; + if ( ( (PersistentCollectionType) types[i] ).isArrayType() ) { + pc = arrayHolders.remove( values[i] ); + } + else if ( values[i] instanceof PersistentCollection ) { + pc = values[i]; + } + + if (pc!=null) { + if ( ( (PersistentCollection) pc ).unsetSession(this) ) collections.remove(pc); + } + } + else if ( types[i].isComponentType() ) { + AbstractComponentType actype = (AbstractComponentType) types[i]; + disassociateCollections( + actype.getPropertyValues( values[i], this ), + actype.getSubtypes() + ); + } } } |