[hibernate-commits] Hibernate SVN: r18321 - in core/branches/Branch_3_3: testsuite/src/test/java/org/hibernate/test/ops and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Dec 23 13:55:06 EST 2009


Author: gbadner
Date: 2009-12-23 13:55:06 -0500 (Wed, 23 Dec 2009)
New Revision: 18321

Modified:
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
   core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/ops/SaveOrUpdateTest.java
Log:
HHH-4735 : Proxy can be associated with a new session when it is already connected to a different one

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java	2009-12-23 18:38:09 UTC (rev 18320)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java	2009-12-23 18:55:06 UTC (rev 18321)
@@ -46,6 +46,7 @@
 	private boolean unwrap;
 
 	private transient SessionImplementor session;
+	private transient EntityKey entityKey; // cached value
 
 	/**
 	 * For serialization from the non-pojo initializers (HHH-3309)
@@ -64,6 +65,7 @@
 		this.entityName = entityName;
 		this.id = id;
 		this.session = session;
+		this.entityKey = generateEntityKeyOrNull();
 	}
 
 	/**
@@ -85,6 +87,7 @@
 	 */
 	public final void setIdentifier(Serializable id) {
 		this.id = id;
+		entityKey = generateEntityKeyOrNull();
 	}
 
 	/**
@@ -110,17 +113,31 @@
 				//TODO: perhaps this should be some other RuntimeException...
 				throw new HibernateException("illegally attempted to associate a proxy with two open Sessions");
 			}
+			else if ( s == null ){
+				unsetSession();
+			}
 			else {
 				session = s;
+				entityKey = generateEntityKeyOrNull();
 			}
 		}
 	}
 
+	private EntityKey generateEntityKeyOrNull() {
+		if ( getIdentifier() == null || session == null || entityName == null ) {
+			return null;
+		}
+		return new EntityKey(
+				getIdentifier(), session.getFactory().getEntityPersister( entityName ), session.getEntityMode()
+		);
+	}
+
 	/**
 	 * {@inheritDoc}
 	 */
 	public void unsetSession() {
 		session = null;
+		entityKey = null;
 	}
 
 	/**
@@ -162,11 +179,16 @@
 	 * @return Value for property 'connectedToSession'.
 	 */
 	protected final boolean isConnectedToSession() {
-		return session!=null &&
-				session.isOpen() &&
-				session.getPersistenceContext().containsProxy(this);
+		return getProxyOrNull() != null;
 	}
 
+	private Object getProxyOrNull() {
+		if ( session != null && session.isOpen() && entityKey != null ) {
+			return session.getPersistenceContext().getProxy( entityKey );
+		}
+		return null;
+	}
+
 	/**
 	 * Return the underlying persistent object, initializing if necessary
 	 */

Modified: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/ops/SaveOrUpdateTest.java
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/ops/SaveOrUpdateTest.java	2009-12-23 18:38:09 UTC (rev 18320)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/ops/SaveOrUpdateTest.java	2009-12-23 18:55:06 UTC (rev 18321)
@@ -6,6 +6,7 @@
 import org.hibernate.Hibernate;
 import org.hibernate.Session;
 import org.hibernate.Transaction;
+import org.hibernate.HibernateException;
 import org.hibernate.junit.functional.FunctionalTestCase;
 import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
 import org.hibernate.intercept.FieldInterceptionHelper;
@@ -388,6 +389,23 @@
 		assertTrue( s1.contains( child.getParent() ) );
 
 		Session s2 = openSession();
+		try {
+			s2.getTransaction().begin();
+			s2.saveOrUpdate( child );
+			fail();
+		}
+		catch ( HibernateException ex ) {
+			// expected because parent is connected to s1
+		}
+		finally {
+			s2.getTransaction().rollback();
+		}
+		s2.close();
+
+		s1.evict( child.getParent() );
+		assertFalse( s1.contains( child.getParent() ) );
+
+		s2 = openSession();
 		s2.getTransaction().begin();
 		s2.saveOrUpdate( child );
 		assertTrue( s2.contains( child ) );



More information about the hibernate-commits mailing list