[hibernate-commits] Hibernate SVN: r17948 - in core/trunk/core/src/main/java/org/hibernate: impl and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Nov 10 03:38:09 EST 2009


Author: gbadner
Date: 2009-11-10 03:38:09 -0500 (Tue, 10 Nov 2009)
New Revision: 17948

Added:
   core/trunk/core/src/main/java/org/hibernate/engine/NonFlushedChanges.java
   core/trunk/core/src/main/java/org/hibernate/impl/NonFlushedChangesImpl.java
Modified:
   core/trunk/core/src/main/java/org/hibernate/engine/CollectionEntry.java
   core/trunk/core/src/main/java/org/hibernate/engine/CollectionKey.java
   core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java
   core/trunk/core/src/main/java/org/hibernate/engine/EntityKey.java
   core/trunk/core/src/main/java/org/hibernate/engine/SessionImplementor.java
   core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java
   core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
   core/trunk/core/src/main/java/org/hibernate/util/MarkerObject.java
Log:
HHH-2762 : SessionImplementor.getNonFlushedChanges()/applyNonFlushedChanges() API and initial implementation

Modified: core/trunk/core/src/main/java/org/hibernate/engine/CollectionEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/CollectionEntry.java	2009-11-07 00:38:39 UTC (rev 17947)
+++ core/trunk/core/src/main/java/org/hibernate/engine/CollectionEntry.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -266,7 +266,7 @@
 	}
 	
 	void afterDeserialize(SessionFactoryImplementor factory) {
-		loadedPersister = factory.getCollectionPersister(role);
+		loadedPersister = ( factory == null ? null : factory.getCollectionPersister(role) );
 	}
 
 	public boolean wasDereferenced() {
@@ -414,7 +414,7 @@
 				( String ) ois.readObject(),
 		        ( Serializable ) ois.readObject(),
 		        ( Serializable ) ois.readObject(),
-		        session.getFactory()
+		        ( session == null ? null : session.getFactory() )
 		);
 	}
 }
\ No newline at end of file

Modified: core/trunk/core/src/main/java/org/hibernate/engine/CollectionKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/CollectionKey.java	2009-11-07 00:38:39 UTC (rev 17947)
+++ core/trunk/core/src/main/java/org/hibernate/engine/CollectionKey.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -128,7 +128,7 @@
 		        ( Serializable ) ois.readObject(),
 		        ( Type ) ois.readObject(),
 		        EntityMode.parse( ( String ) ois.readObject() ),
-		        session.getFactory()
+		        ( session == null ? null : session.getFactory() )
 		);
 	}
 }
\ No newline at end of file

Modified: core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java	2009-11-07 00:38:39 UTC (rev 17947)
+++ core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -104,7 +104,7 @@
 			final boolean isBeingReplicated,
 			final boolean loadedWithLazyPropertiesUnfetched) {
 		this.entityName = entityName;
-		this.persister = factory.getEntityPersister( entityName );
+		this.persister = ( factory == null ? null : factory.getEntityPersister( entityName ) );
 		this.id = id;
 		this.entityMode = entityMode;
 		this.status = status;
@@ -322,7 +322,7 @@
 			ObjectInputStream ois,
 	        SessionImplementor session) throws IOException, ClassNotFoundException {
 		return new EntityEntry(
-				session.getFactory(),
+				( session == null ? null : session.getFactory() ),
 		        ( String ) ois.readObject(),
 				( Serializable ) ois.readObject(),
 	            EntityMode.parse( ( String ) ois.readObject() ),

Modified: core/trunk/core/src/main/java/org/hibernate/engine/EntityKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/EntityKey.java	2009-11-07 00:38:39 UTC (rev 17947)
+++ core/trunk/core/src/main/java/org/hibernate/engine/EntityKey.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -171,7 +171,7 @@
 		        ( String ) ois.readObject(),
 		        ( Type ) ois.readObject(),
 		        ois.readBoolean(),
-		        session.getFactory(),
+		        ( session == null ? null : session.getFactory() ),
 		        EntityMode.parse( ( String ) ois.readObject() )
 		);
 	}

Added: core/trunk/core/src/main/java/org/hibernate/engine/NonFlushedChanges.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/NonFlushedChanges.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/engine/NonFlushedChanges.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.engine;
+
+/**
+ * This interface defines the public API for changes to an EventSource that have not
+ * been flushed to the database.
+ *
+ * @author Gail Badner
+ */
+
+import java.io.Serializable;
+import org.hibernate.event.EventSource;
+
+public interface NonFlushedChanges extends Serializable {
+
+	/**
+	 * Extracts the non-flushed Changes from an EventSource into this NonFlushedChanges object.
+	 * <p>
+	 * @param source
+	 */
+	void extractFromSession(EventSource source);
+
+	/**
+	 * Remove the non-flushed changes from this NonFlushedChanges object.
+	 */
+	void clear();
+}
\ No newline at end of file

Modified: core/trunk/core/src/main/java/org/hibernate/engine/SessionImplementor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/SessionImplementor.java	2009-11-07 00:38:39 UTC (rev 17947)
+++ core/trunk/core/src/main/java/org/hibernate/engine/SessionImplementor.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -287,6 +287,24 @@
 	 */
 	int executeNativeUpdate(NativeSQLQuerySpecification specification, QueryParameters queryParameters) throws HibernateException;
 
+
+	/**
+	 * Return changes to this session that have not been flushed yet.
+	 *
+	 * @return The non-flushed changes.
+	 */
+	public NonFlushedChanges getNonFlushedChanges() throws HibernateException;
+
+	/**
+	 * Apply non-flushed changes from a different session to this session. It is assumed
+	 * that this SessionImpl is "clean" (e.g., has no non-flushed changes, no cached entities,
+	 * no cached collections, no queued actions). The specified NonFlushedChanges object cannot
+	 * be bound to any session.
+	 * <p/>
+	 * @param nonFlushedChanges the non-flushed changes
+	 */
+	public void applyNonFlushedChanges(NonFlushedChanges nonFlushedChanges) throws HibernateException;	
+
 	// copied from Session:
 	
 	public EntityMode getEntityMode();

Added: core/trunk/core/src/main/java/org/hibernate/impl/NonFlushedChangesImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/NonFlushedChangesImpl.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/impl/NonFlushedChangesImpl.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -0,0 +1,109 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.impl;
+
+/**
+ * An implementation of NonFlushedChanges.
+ *
+ * @author Gail Badner
+ */
+
+import org.hibernate.engine.NonFlushedChanges;
+import org.hibernate.engine.ActionQueue;
+import org.hibernate.engine.StatefulPersistenceContext;
+import org.hibernate.event.EventSource;
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.io.Serializable;
+import java.io.ObjectInputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class NonFlushedChangesImpl implements NonFlushedChanges {
+
+	private static final Logger log = LoggerFactory.getLogger(NonFlushedChangesImpl.class);
+
+	private static class SessionNonFlushedChanges implements Serializable {
+		private transient EntityMode entityMode;
+		private transient ActionQueue actionQueue;
+		private transient StatefulPersistenceContext persistenceContext;
+
+		public SessionNonFlushedChanges(EventSource session) {
+			this.entityMode = session.getEntityMode();
+			this.actionQueue = session.getActionQueue();
+			this.persistenceContext = ( StatefulPersistenceContext ) session.getPersistenceContext();
+		}
+
+		private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+			ois.defaultReadObject();
+			entityMode = EntityMode.parse( ( String ) ois.readObject() );
+			persistenceContext = StatefulPersistenceContext.deserialize( ois, null );
+			actionQueue = ActionQueue.deserialize( ois, null );
+		}
+
+		private void writeObject(ObjectOutputStream oos) throws IOException {
+			log.trace( "serializing SessionNonFlushedChanges" );
+			oos.defaultWriteObject();
+			oos.writeObject( entityMode.toString() );
+			persistenceContext.serialize( oos );
+			actionQueue.serialize( oos );
+		}
+	}
+	private Map nonFlushedChangesByEntityMode = new HashMap();
+
+	public NonFlushedChangesImpl( EventSource session ) {
+		extractFromSession( session );
+	}
+
+	public void extractFromSession(EventSource session) {
+		if ( nonFlushedChangesByEntityMode.containsKey( session.getEntityMode() ) ) {
+			throw new AssertionFailure( "Already has non-flushed changes for entity mode: " + session.getEntityMode() );
+		}
+		nonFlushedChangesByEntityMode.put( session.getEntityMode(), new SessionNonFlushedChanges( session ) );
+	}
+
+	private SessionNonFlushedChanges getSessionNonFlushedChanges(EntityMode entityMode) {
+		return ( SessionNonFlushedChanges ) nonFlushedChangesByEntityMode.get( entityMode );
+	}
+
+	/* package-protected */
+	ActionQueue getActionQueue(EntityMode entityMode) {
+		return getSessionNonFlushedChanges( entityMode ).actionQueue;
+	}	
+
+	/* package-protected */
+	StatefulPersistenceContext getPersistenceContext(EntityMode entityMode) {
+		return getSessionNonFlushedChanges( entityMode ).persistenceContext;
+	}
+
+	public void clear() {
+		nonFlushedChangesByEntityMode.clear();
+	}
+}
\ No newline at end of file

Modified: core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java	2009-11-07 00:38:39 UTC (rev 17947)
+++ core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -28,6 +28,8 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.Collection;
@@ -72,6 +74,7 @@
 import org.hibernate.engine.CollectionEntry;
 import org.hibernate.engine.EntityEntry;
 import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.NonFlushedChanges;
 import org.hibernate.engine.PersistenceContext;
 import org.hibernate.engine.QueryParameters;
 import org.hibernate.engine.StatefulPersistenceContext;
@@ -127,9 +130,11 @@
 import org.hibernate.stat.SessionStatistics;
 import org.hibernate.stat.SessionStatisticsImpl;
 import org.hibernate.type.Type;
+import org.hibernate.type.SerializationException;
 import org.hibernate.util.ArrayHelper;
 import org.hibernate.util.CollectionHelper;
 import org.hibernate.util.StringHelper;
+import org.hibernate.util.SerializationHelper;
 
 
 /**
@@ -377,6 +382,138 @@
 		}
 	}
 
+	/**
+	 * Return changes to this session and its child sessions that have not been flushed yet.
+	 * <p/>
+	 * @return The non-flushed changes.
+	 */
+	public NonFlushedChanges getNonFlushedChanges() throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		NonFlushedChanges nonFlushedChanges = new NonFlushedChangesImpl( this );
+		if ( childSessionsByEntityMode != null ) {
+			Iterator it = childSessionsByEntityMode.values().iterator();
+			while ( it.hasNext() ) {
+				nonFlushedChanges.extractFromSession( ( EventSource ) it.next() );
+			}
+		}
+		return nonFlushedChanges;
+	}
+
+	/**
+	 * Apply non-flushed changes from a different session to this session. It is assumed
+	 * that this SessionImpl is "clean" (e.g., has no non-flushed changes, no cached entities,
+	 * no cached collections, no queued actions). The specified NonFlushedChanges object cannot
+	 * be bound to any session.
+	 * <p/>
+	 * @param nonFlushedChanges the non-flushed changes
+	 */
+	public void applyNonFlushedChanges(NonFlushedChanges nonFlushedChanges) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		replacePersistenceContext( ( ( NonFlushedChangesImpl ) nonFlushedChanges ).getPersistenceContext( entityMode) );
+		replaceActionQueue( ( ( NonFlushedChangesImpl ) nonFlushedChanges ).getActionQueue( entityMode ) );
+		if ( childSessionsByEntityMode != null ) {
+			for ( Iterator it = childSessionsByEntityMode.values().iterator(); it.hasNext(); ) {
+				( ( SessionImpl ) it.next() ).applyNonFlushedChanges( nonFlushedChanges );
+			}
+		}
+	}
+
+	private void replacePersistenceContext(StatefulPersistenceContext persistenceContextNew) {
+		if ( persistenceContextNew.getSession() != null ) {
+			throw new IllegalStateException( "new persistence context is already connected to a session " );
+		}
+		persistenceContext.clear();
+		ObjectInputStream ois = null;
+		try {
+			ois = new ObjectInputStream( new ByteArrayInputStream( serializePersistenceContext( persistenceContextNew ) ) );
+			this.persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
+		}
+		catch (IOException ex) {
+			throw new SerializationException( "could not deserialize the persistence context",  ex );
+		}
+		catch (ClassNotFoundException ex) {
+			throw new SerializationException( "could not deserialize the persistence context", ex );
+		}
+		finally {
+			try {
+				if (ois != null) ois.close();
+			}
+			catch (IOException ex) {}
+		}
+	}
+
+	private static byte[] serializePersistenceContext(StatefulPersistenceContext pc) {
+		ByteArrayOutputStream baos = new ByteArrayOutputStream( 512 );
+		ObjectOutputStream oos = null;
+		try {
+			oos = new ObjectOutputStream( baos );
+			( ( StatefulPersistenceContext ) pc ).serialize( oos );
+		}
+		catch (IOException ex) {
+			throw new SerializationException( "could not serialize persistence context", ex );
+		}
+		finally {
+			if ( oos != null ) {
+				try {
+					oos.close();
+				}
+				catch( IOException ex ) {
+					//ignore
+				}
+			}
+		}
+		return baos.toByteArray();
+	}
+
+	private void replaceActionQueue(ActionQueue actionQueueNew) {
+		if ( actionQueue.hasAnyQueuedActions() ) {
+			throw new IllegalStateException( "cannot replace an ActionQueue with queued actions " );
+		}
+		actionQueue.clear();
+		ObjectInputStream ois = null;
+		try {
+			ois = new ObjectInputStream( new ByteArrayInputStream( serializeActionQueue( actionQueueNew ) ) );
+			actionQueue = ActionQueue.deserialize( ois, this );
+		}
+		catch (IOException ex) {
+			throw new SerializationException( "could not deserialize the action queue",  ex );
+		}
+		catch (ClassNotFoundException ex) {
+			throw new SerializationException( "could not deserialize the action queue", ex );
+		}
+		finally {
+			try {
+				if (ois != null) ois.close();
+			}
+			catch (IOException ex) {}
+		}
+	}
+
+	private static byte[] serializeActionQueue(ActionQueue actionQueue) {
+		ByteArrayOutputStream baos = new ByteArrayOutputStream( 512 );
+		ObjectOutputStream oos = null;
+		try {
+			oos = new ObjectOutputStream( baos );
+			actionQueue.serialize( oos );
+		}
+		catch (IOException ex) {
+			throw new SerializationException( "could not serialize action queue", ex );
+		}
+		finally {
+			if ( oos != null ) {
+				try {
+					oos.close();
+				}
+				catch( IOException ex ) {
+					//ignore
+				}
+			}
+		}
+		return baos.toByteArray();
+	}
+
 	public boolean shouldAutoClose() {
 		return isAutoCloseSessionEnabled() && !isClosed();
 	}

Modified: core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java	2009-11-07 00:38:39 UTC (rev 17947)
+++ core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -55,6 +55,7 @@
 import org.hibernate.engine.StatefulPersistenceContext;
 import org.hibernate.engine.Versioning;
 import org.hibernate.engine.LoadQueryInfluencers;
+import org.hibernate.engine.NonFlushedChanges;
 import org.hibernate.engine.query.HQLQueryPlan;
 import org.hibernate.engine.query.NativeSQLQueryPlan;
 import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
@@ -621,6 +622,14 @@
 
 	public void flush() {}
 
+	public NonFlushedChanges getNonFlushedChanges() {
+		throw new UnsupportedOperationException();
+	}
+
+	public void applyNonFlushedChanges(NonFlushedChanges nonFlushedChanges) {
+		throw new UnsupportedOperationException();
+	}
+
 	public String getFetchProfile() {
 		return null;
 	}

Modified: core/trunk/core/src/main/java/org/hibernate/util/MarkerObject.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/MarkerObject.java	2009-11-07 00:38:39 UTC (rev 17947)
+++ core/trunk/core/src/main/java/org/hibernate/util/MarkerObject.java	2009-11-10 08:38:09 UTC (rev 17948)
@@ -24,10 +24,12 @@
  */
 package org.hibernate.util;
 
+import java.io.Serializable;
+
 /**
  * @author Gavin King
  */
-public class MarkerObject {
+public class MarkerObject implements Serializable {
 	private String name;
 	
 	public MarkerObject(String name) {



More information about the hibernate-commits mailing list