[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