[hibernate-commits] Hibernate SVN: r10795 - in trunk/Hibernate3: src/org/hibernate/event/def test/org/hibernate/test/discriminator test/org/hibernate/test/joinedsubclass

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Nov 13 13:52:35 EST 2006


Author: steve.ebersole at jboss.com
Date: 2006-11-13 13:52:33 -0500 (Mon, 13 Nov 2006)
New Revision: 10795

Modified:
   trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java
   trunk/Hibernate3/test/org/hibernate/test/discriminator/DiscriminatorTest.java
   trunk/Hibernate3/test/org/hibernate/test/joinedsubclass/JoinedSubclassTest.java
Log:
HHH-1460 : subclass/get consistency

Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java	2006-11-13 18:47:46 UTC (rev 10794)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java	2006-11-13 18:52:33 UTC (rev 10795)
@@ -8,7 +8,6 @@
 import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
 import org.hibernate.NonUniqueObjectException;
-import org.hibernate.ObjectDeletedException;
 import org.hibernate.PersistentObjectException;
 import org.hibernate.TypeMismatchException;
 import org.hibernate.EntityMode;
@@ -43,11 +42,14 @@
  */
 public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener implements LoadEventListener {
 
+	public static final Object REMOVED_ENTITY_MARKER = new Object();
+	public static final Object INCONSISTENT_RTN_CLASS_MARKER = new Object();
+	public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE;
+
 	private static final Log log = LogFactory.getLog(DefaultLoadEventListener.class);
 
-	public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE;
 
-	/** 
+	/**
 	 * Handle the given load event.
 	 *
 	 * @param event The load event to be handled.
@@ -67,9 +69,9 @@
 		}
 
 		if ( persister == null ) {
-			throw new HibernateException( 
-					"Unable to locate persister: " + 
-					event.getEntityClassName() 
+			throw new HibernateException(
+					"Unable to locate persister: " +
+					event.getEntityClassName()
 				);
 		}
 
@@ -118,12 +120,12 @@
 	 * @throws HibernateException
 	 */
 	protected Object load(
-		final LoadEvent event, 
-		final EntityPersister persister, 
-		final EntityKey keyToLoad, 
+		final LoadEvent event,
+		final EntityPersister persister,
+		final EntityKey keyToLoad,
 		final LoadEventListener.LoadType options)
 	throws HibernateException {
-	
+
 		if ( event.getInstanceToLoad() != null ) {
 			if ( event.getSession().getPersistenceContext().getEntry( event.getInstanceToLoad() ) != null ) {
 				throw new PersistentObjectException(
@@ -135,9 +137,9 @@
 		}
 
 		Object entity = doLoad(event, persister, keyToLoad, options);
-		
+
 		boolean isOptionalInstance = event.getInstanceToLoad() != null;
-		
+
 		if ( !options.isAllowNulls() || isOptionalInstance ) {
 			if ( entity == null ) {
 				event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( event.getEntityClassName(), event.getEntityId() );
@@ -151,7 +153,7 @@
 		return entity;
 	}
 
-	/** 
+	/**
 	 * Based on configured options, will either return a pre-existing proxy,
 	 * generate a new proxy, or perform an actual load.
 	 *
@@ -159,15 +161,15 @@
 	 * @throws HibernateException
 	 */
 	protected Object proxyOrLoad(
-		final LoadEvent event, 
+		final LoadEvent event,
 		final EntityPersister persister,
-		final EntityKey keyToLoad, 
-		final LoadEventListener.LoadType options) 
+		final EntityKey keyToLoad,
+		final LoadEventListener.LoadType options)
 	throws HibernateException {
-		
+
 		if ( log.isTraceEnabled() ) {
 			log.trace(
-					"loading entity: " + 
+					"loading entity: " +
 					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
 				);
 		}
@@ -193,7 +195,7 @@
 					return load(event, persister, keyToLoad, options);
 				}
 			}
-			
+
 		}
 	}
 
@@ -202,11 +204,11 @@
 	 * Initialize it if necessary; narrow if necessary.
 	 */
 	private Object returnNarrowedProxy(
-			final LoadEvent event, 
-			final EntityPersister persister, 
-			final EntityKey keyToLoad, 
-			final LoadEventListener.LoadType options, 
-			final PersistenceContext persistenceContext, 
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options,
+			final PersistenceContext persistenceContext,
 			final Object proxy
 	) {
 		log.trace("entity proxy found in session cache");
@@ -223,16 +225,16 @@
 		}
 		return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl );
 	}
-	
+
 	/**
 	 * Given that there is no pre-existing proxy.
 	 * Check if the entity is already loaded. If it is, return the entity,
 	 * otherwise create and return a proxy.
 	 */
 	private Object createProxyIfNecessary(
-			final LoadEvent event, 
-			final EntityPersister persister, 
-			final EntityKey keyToLoad, 
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
 			final LoadEventListener.LoadType options,
 			final PersistenceContext persistenceContext
 	) {
@@ -259,7 +261,7 @@
 		}
 	}
 
-	/** 
+	/**
 	 * If the class to be loaded has been configured with a cache, then lock
 	 * given id in that cache and then perform the load.
 	 *
@@ -267,22 +269,22 @@
 	 * @throws HibernateException
 	 */
 	protected Object lockAndLoad(
-		final LoadEvent event, 
+		final LoadEvent event,
 		final EntityPersister persister,
-		final EntityKey keyToLoad, 
+		final EntityKey keyToLoad,
 		final LoadEventListener.LoadType options,
-		final SessionImplementor source) 
+		final SessionImplementor source)
 	throws HibernateException {
-		
+
 		CacheConcurrencyStrategy.SoftLock lock = null;
 		final CacheKey ck;
 		if ( persister.hasCache() ) {
-			ck = new CacheKey( 
-					event.getEntityId(), 
-					persister.getIdentifierType(), 
-					persister.getRootEntityName(), 
-					source.getEntityMode(), 
-					source.getFactory() 
+			ck = new CacheKey(
+					event.getEntityId(),
+					persister.getIdentifierType(),
+					persister.getRootEntityName(),
+					source.getEntityMode(),
+					source.getFactory()
 				);
 			lock = persister.getCache().lock(ck, null );
 		}
@@ -302,11 +304,10 @@
 
 		Object proxy = event.getSession().getPersistenceContext()
 				.proxyFor( persister, keyToLoad, entity );
-		
+
 		return proxy;
 	}
 
-	protected static final Object REMOVED_ENTITY_MARKER = new Object();
 
 	/**
 	 * Coordinates the efforts to load a given entity.  First, an attempt is
@@ -314,28 +315,35 @@
 	 * an attempt is made to locate it in second-level cache.  Lastly, an
 	 * attempt is made to load it directly from the datasource.
 	 *
-	 * @return The loaded entity.
+	 * @param event The load event
+	 * @param persister The persister for the entity being requested for load
+	 * @param keyToLoad The EntityKey representing the entity to be loaded.
+	 * @param options The load options.
+	 * @return The loaded entity, or null.
 	 * @throws HibernateException
 	 */
 	protected Object doLoad(
-		final LoadEvent event, 
-		final EntityPersister persister,
-		final EntityKey keyToLoad, 
-		final LoadEventListener.LoadType options) 
-	throws HibernateException {
-		
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options) throws HibernateException {
+
 		if ( log.isTraceEnabled() ) {
 			log.trace(
-					"attempting to resolve: " + 
+					"attempting to resolve: " +
 					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
 				);
 		}
 
-		Object entity = loadFromSessionCache(event, keyToLoad, options);
+		Object entity = loadFromSessionCache( event, keyToLoad, options );
 		if ( entity == REMOVED_ENTITY_MARKER ) {
 			log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" );
 			return null;
 		}
+		if ( entity == INCONSISTENT_RTN_CLASS_MARKER ) {
+			log.debug( "load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null" );
+			return null;
+		}
 		if ( entity != null ) {
 			if ( log.isTraceEnabled() ) {
 				log.trace(
@@ -346,13 +354,6 @@
 			return entity;
 		}
 
-		// Entity not found in session; before going any further, see if we
-		// already determined that this entity does not exist
-		/*if ( event.getSession().getPersistenceContext().isNonExistant(keyToLoad) ) {
-			if ( log.isTraceEnabled() ) log.trace("entity does not exist");
-			return null;
-		}*/
-
 		entity = loadFromSecondLevelCache(event, persister, options);
 		if ( entity != null ) {
 			if ( log.isTraceEnabled() ) {
@@ -378,30 +379,26 @@
 	 * Performs the process of loading an entity from the configured
 	 * underlying datasource.
 	 *
+	 * @param event The load event
+	 * @param persister The persister for the entity being requested for load
+	 * @param keyToLoad The EntityKey representing the entity to be loaded.
+	 * @param options The load options.
 	 * @return The object loaded from the datasource, or null if not found.
 	 * @throws HibernateException
 	 */
 	protected Object loadFromDatasource(
-		final LoadEvent event,
-		final EntityPersister persister,
-		final EntityKey keyToLoad,
-		final LoadEventListener.LoadType options) 
-	throws HibernateException {
-		
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options) throws HibernateException {
 		final SessionImplementor source = event.getSession();
-		
 		Object entity = persister.load(
-				event.getEntityId(), 
-				event.getInstanceToLoad(), 
-				event.getLockMode(), 
+				event.getEntityId(),
+				event.getInstanceToLoad(),
+				event.getLockMode(),
 				source
-			);
-		
-		/*if ( entity == null ) {
-			//remember it doesn't exist, in case of next time
-			source.getPersistenceContext().addNonExistantEntityKey(keyToLoad);
-		}*/
-		
+		);
+
 		if ( event.isAssociationFetch() && source.getFactory().getStatistics().isStatisticsEnabled() ) {
 			source.getFactory().getStatisticsImplementor().fetchEntity( event.getEntityClassName() );
 		}
@@ -410,22 +407,30 @@
 	}
 
 	/**
-	 * Attempts to locate the entity in the session-level cache.  If
-	 * checkDeleted was set to true, then if the entity is found in the
+	 * Attempts to locate the entity in the session-level cache.
+	 * <p/>
+	 * If allowed to return nulls, then if the entity happens to be found in
+	 * the session cache, we check the entity type for proper handling
+	 * of entity hierarchies.
+	 * <p/>
+	 * If checkDeleted was set to true, then if the entity is found in the
 	 * session-level cache, it's current status within the session cache
 	 * is checked to see if it has previously been scheduled for deletion.
 	 *
+	 * @param event The load event
+	 * @param keyToLoad The EntityKey representing the entity to be loaded.
+	 * @param options The load options.
 	 * @return The entity from the session-level cache, or null.
-	 * @throws HibernateException
+	 * @throws HibernateException Generally indicates problems applying a lock-mode.
 	 */
 	protected Object loadFromSessionCache(
-		final LoadEvent event,
-		final EntityKey keyToLoad,
-		final LoadEventListener.LoadType options) 
-	throws HibernateException {
-		
+			final LoadEvent event,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options) throws HibernateException {
+
 		SessionImplementor session = event.getSession();
 		Object old = session.getEntityUsingInterceptor( keyToLoad );
+
 		if ( old != null ) {
 			// this object was already loaded
 			EntityEntry oldEntry = session.getPersistenceContext().getEntry( old );
@@ -435,52 +440,61 @@
 					return REMOVED_ENTITY_MARKER;
 				}
 			}
+			if ( options.isAllowNulls() ) {
+				EntityPersister persister = event.getSession().getFactory().getEntityPersister( event.getEntityClassName() );
+				if ( ! persister.isInstance( old, event.getSession().getEntityMode() ) ) {
+					return INCONSISTENT_RTN_CLASS_MARKER;
+				}
+			}
 			upgradeLock( old, oldEntry, event.getLockMode(), session );
 		}
+
 		return old;
 	}
 
 	/**
 	 * Attempts to load the entity from the second-level cache.
 	 *
+	 * @param event The load event
+	 * @param persister The persister for the entity being requested for load
+	 * @param options The load options.
 	 * @return The entity from the second-level cache, or null.
 	 * @throws HibernateException
 	 */
 	protected Object loadFromSecondLevelCache(
-		final LoadEvent event,
-		final EntityPersister persister,
-		final LoadEventListener.LoadType options) 
-	throws HibernateException {
-		
+			final LoadEvent event,
+			final EntityPersister persister,
+			final LoadEventListener.LoadType options) throws HibernateException {
+
 		final SessionImplementor source = event.getSession();
-		
-		final boolean useCache = persister.hasCache() && 
-			source.getCacheMode().isGetEnabled() && 
+
+		final boolean useCache = persister.hasCache() &&
+			source.getCacheMode().isGetEnabled() &&
 			event.getLockMode().lessThan(LockMode.READ);
-		
+
 		if (useCache) {
-			
+
 			final SessionFactoryImplementor factory = source.getFactory();
-			
-			final CacheKey ck = new CacheKey( 
-					event.getEntityId(), 
-					persister.getIdentifierType(), 
+
+			final CacheKey ck = new CacheKey(
+					event.getEntityId(),
+					persister.getIdentifierType(),
 					persister.getRootEntityName(),
-					source.getEntityMode(), 
+					source.getEntityMode(),
 					source.getFactory()
 				);
 			Object ce = persister.getCache()
 				.get( ck, source.getTimestamp() );
-			
+
 			if ( factory.getStatistics().isStatisticsEnabled() ) {
 				if (ce==null) {
-					factory.getStatisticsImplementor().secondLevelCacheMiss( 
-						persister.getCache().getRegionName() 
+					factory.getStatisticsImplementor().secondLevelCacheMiss(
+						persister.getCache().getRegionName()
 					);
 				}
 				else {
-					factory.getStatisticsImplementor().secondLevelCacheHit( 
-						persister.getCache().getRegionName() 
+					factory.getStatisticsImplementor().secondLevelCacheHit(
+						persister.getCache().getRegionName()
 					);
 				}
 			}
@@ -489,7 +503,7 @@
 
 				CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure()
 						.destructure(ce, factory);
-			
+
 				// Entity was found in second-level cache...
 				return assembleCacheEntry(
 						entry,
@@ -499,21 +513,20 @@
 					);
 			}
 		}
-		
+
 		return null;
 	}
 
 	private Object assembleCacheEntry(
-		final CacheEntry entry,
-		final Serializable id,
-		final EntityPersister persister,
-		final LoadEvent event)
-	throws HibernateException {
-		
+			final CacheEntry entry,
+			final Serializable id,
+			final EntityPersister persister,
+			final LoadEvent event) throws HibernateException {
+
 		final Object optionalObject = event.getInstanceToLoad();
 		final EventSource session = event.getSession();
 		final SessionFactoryImplementor factory = session.getFactory();
-		
+
 		if ( log.isTraceEnabled() ) {
 			log.trace(
 					"assembling entity from second-level cache: " +
@@ -522,15 +535,15 @@
 		}
 
 		EntityPersister subclassPersister = factory.getEntityPersister( entry.getSubclass() );
-		Object result = optionalObject == null ? 
+		Object result = optionalObject == null ?
 				session.instantiate( subclassPersister, id ) : optionalObject;
-				
+
 		// make it circular-reference safe
-		TwoPhaseLoad.addUninitializedCachedEntity( 
-				new EntityKey( id, subclassPersister, session.getEntityMode() ), 
-				result, 
-				subclassPersister, 
-				LockMode.NONE, 
+		TwoPhaseLoad.addUninitializedCachedEntity(
+				new EntityKey( id, subclassPersister, session.getEntityMode() ),
+				result,
+				subclassPersister,
+				LockMode.NONE,
 				entry.areLazyPropertiesUnfetched(),
 				entry.getVersion(),
 				session
@@ -538,30 +551,30 @@
 
 		Type[] types = subclassPersister.getPropertyTypes();
 		Object[] values = entry.assemble( result, id, subclassPersister, session.getInterceptor(), session ); // intializes result by side-effect
-		TypeFactory.deepCopy( 
-				values, 
-				types, 
-				subclassPersister.getPropertyUpdateability(), 
-				values, 
+		TypeFactory.deepCopy(
+				values,
+				types,
+				subclassPersister.getPropertyUpdateability(),
+				values,
 				session
 			);
-		
+
 		Object version = Versioning.getVersion( values, subclassPersister );
 		if ( log.isTraceEnabled() ) log.trace( "Cached Version: " + version );
-		
+
 		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		persistenceContext.addEntry( 
-				result, 
-				Status.MANAGED, 
-				values, 
-				null, 
-				id, 
-				version, 
-				LockMode.NONE, 
-				true, 
-				subclassPersister, 
-				false, 
-				entry.areLazyPropertiesUnfetched() 
+		persistenceContext.addEntry(
+				result,
+				Status.MANAGED,
+				values,
+				null,
+				id,
+				version,
+				LockMode.NONE,
+				true,
+				subclassPersister,
+				false,
+				entry.areLazyPropertiesUnfetched()
 			);
 		subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session );
 		persistenceContext.initializeNonLazyCollections();
@@ -576,7 +589,7 @@
 		for ( int i = 0; i < listeners.length; i++ ) {
 			listeners[i].onPostLoad(postLoadEvent);
 		}
-		
+
 		return result;
 	}
 

Modified: trunk/Hibernate3/test/org/hibernate/test/discriminator/DiscriminatorTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/discriminator/DiscriminatorTest.java	2006-11-13 18:47:46 UTC (rev 10794)
+++ trunk/Hibernate3/test/org/hibernate/test/discriminator/DiscriminatorTest.java	2006-11-13 18:52:33 UTC (rev 10795)
@@ -3,6 +3,7 @@
 
 import java.util.Iterator;
 import java.util.List;
+import java.math.BigDecimal;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -10,21 +11,22 @@
 import org.hibernate.Hibernate;
 import org.hibernate.Session;
 import org.hibernate.Transaction;
+import org.hibernate.criterion.Property;
 import org.hibernate.test.TestCase;
 
 /**
  * @author Gavin King
  */
 public class DiscriminatorTest extends TestCase {
-	
+
 	public DiscriminatorTest(String str) {
 		super(str);
 	}
-	
-	public void testJoinedSubclass() {
+
+	public void testDiscriminatorSubclass() {
 		Session s = openSession();
 		Transaction t = s.beginTransaction();
-		
+
 		Employee mark = new Employee();
 		mark.setName("Mark");
 		mark.setTitle("internal sales");
@@ -32,7 +34,7 @@
 		mark.setAddress("buckhead");
 		mark.setZip("30305");
 		mark.setCountry("USA");
-		
+
 		Customer joe = new Customer();
 		joe.setName("Joe");
 		joe.setAddress("San Francisco");
@@ -41,17 +43,17 @@
 		joe.setComments("Very demanding");
 		joe.setSex('M');
 		joe.setSalesperson(mark);
-		
+
 		Person yomomma = new Person();
 		yomomma.setName("mum");
 		yomomma.setSex('F');
-		
+
 		s.save(yomomma);
 		s.save(mark);
 		s.save(joe);
-		
+
 		assertEquals( s.createQuery("from java.io.Serializable").list().size(), 0 );
-		
+
 		assertEquals( s.createQuery("from Person").list().size(), 3 );
 		assertEquals( s.createQuery("from Person p where p.class = Person").list().size(), 1 );
 		assertEquals( s.createQuery("from Person p where p.class = Customer").list().size(), 1 );
@@ -65,7 +67,7 @@
 		}
 		assertEquals( customers.size(), 1 );
 		s.clear();
-		
+
 		customers = s.createQuery("from Customer").list();
 		for ( Iterator iter = customers.iterator(); iter.hasNext(); ) {
 			Customer c = (Customer) iter.next();
@@ -74,11 +76,11 @@
 		}
 		assertEquals( customers.size(), 1 );
 		s.clear();
-		
 
+
 		mark = (Employee) s.get( Employee.class, new Long( mark.getId() ) );
 		joe = (Customer) s.get( Customer.class, new Long( joe.getId() ) );
-		
+
  		mark.setZip("30306");
 		assertEquals( s.createQuery("from Person p where p.address.zip = '30306'").list().size(), 1 );
 		s.delete(mark);
@@ -89,7 +91,79 @@
 		s.close();
 	}
 
-	
+	public void testAccessAsIncorrectSubclass() {
+		Session s = openSession();
+		s.beginTransaction();
+		Employee e = new Employee();
+		e.setName( "Steve" );
+		e.setSex( 'M' );
+		e.setTitle( "grand poobah" );
+		s.save( e );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		Customer c = ( Customer ) s.get( Customer.class, new Long( e.getId() ) );
+		s.getTransaction().commit();
+		s.close();
+		assertNull( c );
+
+		s = openSession();
+		s.beginTransaction();
+		e = ( Employee ) s.get( Employee.class, new Long( e.getId() ) );
+		c = ( Customer ) s.get( Customer.class, new Long( e.getId() ) );
+		s.getTransaction().commit();
+		s.close();
+		assertNotNull( e );
+		assertNull( c );
+
+		s = openSession();
+		s.beginTransaction();
+		s.delete( e );
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testQuerySubclassAttribute() {
+		Session s = openSession();
+		Transaction t = s.beginTransaction();
+		Person p = new Person();
+		p.setName("Emmanuel");
+		p.setSex('M');
+		s.persist(p);
+		Employee q = new Employee();
+		q.setName("Steve");
+		q.setSex('M');
+		q.setTitle("Mr");
+		q.setSalary( new BigDecimal(1000) );
+		s.persist(q);
+
+		List result = s.createQuery("from Person where salary > 100").list();
+		assertEquals( result.size(), 1 );
+		assertSame( result.get(0), q );
+
+		result = s.createQuery("from Person where salary > 100 or name like 'E%'").list();
+		assertEquals( result.size(), 2 );
+
+		result = s.createCriteria(Person.class)
+			.add( Property.forName("salary").gt( new BigDecimal(100) ) )
+			.list();
+		assertEquals( result.size(), 1 );
+		assertSame( result.get(0), q );
+
+		//TODO: make this work:
+		/*result = s.createQuery("select salary from Person where salary > 100").list();
+		assertEquals( result.size(), 1 );
+		assertEquals( result.get(0), new BigDecimal(1000) );*/
+
+		s.delete(p);
+		s.delete(q);
+		t.commit();
+		s.close();
+	}
+
+
 	protected String[] getMappings() {
 		return new String[] { "discriminator/Person.hbm.xml" };
 	}

Modified: trunk/Hibernate3/test/org/hibernate/test/joinedsubclass/JoinedSubclassTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/joinedsubclass/JoinedSubclassTest.java	2006-11-13 18:47:46 UTC (rev 10794)
+++ trunk/Hibernate3/test/org/hibernate/test/joinedsubclass/JoinedSubclassTest.java	2006-11-13 18:52:33 UTC (rev 10795)
@@ -14,25 +14,21 @@
 import org.hibernate.LockMode;
 import org.hibernate.criterion.Expression;
 import org.hibernate.criterion.Property;
-import org.hibernate.dialect.DB2Dialect;
-import org.hibernate.dialect.HSQLDialect;
-import org.hibernate.dialect.MySQLDialect;
-import org.hibernate.dialect.PostgreSQLDialect;
 import org.hibernate.test.TestCase;
 
 /**
  * @author Gavin King
  */
 public class JoinedSubclassTest extends TestCase {
-	
+
 	public JoinedSubclassTest(String str) {
 		super(str);
 	}
-	
+
 	public void testJoinedSubclass() {
 		Session s = openSession();
 		Transaction t = s.beginTransaction();
-		
+
 		Employee mark = new Employee();
 		mark.setName("Mark");
 		mark.setTitle("internal sales");
@@ -40,7 +36,7 @@
 		mark.setAddress("buckhead");
 		mark.setZip("30305");
 		mark.setCountry("USA");
-		
+
 		Customer joe = new Customer();
 		joe.setName("Joe");
 		joe.setAddress("San Francisco");
@@ -49,17 +45,17 @@
 		joe.setComments("Very demanding");
 		joe.setSex('M');
 		joe.setSalesperson(mark);
-		
+
 		Person yomomma = new Person();
 		yomomma.setName("mum");
 		yomomma.setSex('F');
-		
+
 		s.save(yomomma);
 		s.save(mark);
 		s.save(joe);
-		
+
 		assertEquals( s.createQuery("from java.io.Serializable").list().size(), 0 );
-		
+
 		assertEquals( s.createQuery("from Person").list().size(), 3 );
 		assertEquals( s.createQuery("from Person p where p.class = Customer").list().size(), 1 );
 		assertEquals( s.createQuery("from Person p where p.class = Person").list().size(), 1 );
@@ -73,7 +69,7 @@
 		}
 		assertEquals( customers.size(), 1 );
 		s.clear();
-		
+
 		customers = s.createQuery("from Customer").list();
 		for ( Iterator iter = customers.iterator(); iter.hasNext(); ) {
 			Customer c = (Customer) iter.next();
@@ -82,20 +78,20 @@
 		}
 		assertEquals( customers.size(), 1 );
 		s.clear();
-		
 
+
 		mark = (Employee) s.get( Employee.class, new Long( mark.getId() ) );
 		joe = (Customer) s.get( Customer.class, new Long( joe.getId() ) );
-		
+
  		mark.setZip("30306");
 		assertEquals( s.createQuery("from Person p where p.address.zip = '30306'").list().size(), 1 );
 
-		if ( ! supportsRowValueConstructorSyntaxInInList() ) {
-			s.createCriteria(Person.class).add( 
-					Expression.in("address", new Address[] { mark.getAddress(), joe.getAddress() } ) 
+		if ( supportsRowValueConstructorSyntaxInInList() ) {
+			s.createCriteria(Person.class).add(
+					Expression.in("address", new Address[] { mark.getAddress(), joe.getAddress() } )
 			).list();
 		}
-		
+
 		s.delete(mark);
 		s.delete(joe);
 		s.delete(yomomma);
@@ -103,7 +99,41 @@
 		t.commit();
 		s.close();
 	}
-	
+
+	public void testAccessAsIncorrectSubclass() {
+		Session s = openSession();
+		s.beginTransaction();
+		Employee e = new Employee();
+		e.setName( "Steve" );
+		e.setSex( 'M' );
+		e.setTitle( "grand poobah" );
+		s.save( e );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.beginTransaction();
+		Customer c = ( Customer ) s.get( Customer.class, new Long( e.getId() ) );
+		s.getTransaction().commit();
+		s.close();
+		assertNull( c );
+
+		s = openSession();
+		s.beginTransaction();
+		e = ( Employee ) s.get( Employee.class, new Long( e.getId() ) );
+		c = ( Customer ) s.get( Customer.class, new Long( e.getId() ) );
+		s.getTransaction().commit();
+		s.close();
+		assertNotNull( e );
+		assertNull( c );
+
+		s = openSession();
+		s.beginTransaction();
+		s.delete( e );
+		s.getTransaction().commit();
+		s.close();
+	}
+
 	public void testQuerySubclassAttribute() {
 		Session s = openSession();
 		Transaction t = s.beginTransaction();
@@ -121,9 +151,9 @@
 		List result = s.createQuery("from Person where salary > 100").list();
 		assertEquals( result.size(), 1 );
 		assertSame( result.get(0), q );
-		
+
 		result = s.createQuery("from Person where salary > 100 or name like 'E%'").list();
-		assertEquals( result.size(), 2 );		
+		assertEquals( result.size(), 2 );
 
 		result = s.createCriteria(Person.class)
 			.add( Property.forName("salary").gt( new BigDecimal(100) ) )
@@ -135,7 +165,7 @@
 		/*result = s.createQuery("select salary from Person where salary > 100").list();
 		assertEquals( result.size(), 1 );
 		assertEquals( result.get(0), new BigDecimal(1000) );*/
-		
+
 		s.delete(p);
 		s.delete(q);
 		t.commit();
@@ -168,7 +198,8 @@
 		s.close();
 
 	}
-	
+
+
 	protected String[] getMappings() {
 		return new String[] { "joinedsubclass/Person.hbm.xml" };
 	}




More information about the hibernate-commits mailing list