diff --git a/src/org/hibernate/action/CollectionRecreateAction.java b/src/org/hibernate/action/CollectionRecreateAction.java index e0e65df2db..20941f213a 100644 --- a/src/org/hibernate/action/CollectionRecreateAction.java +++ b/src/org/hibernate/action/CollectionRecreateAction.java @@ -21,7 +21,11 @@ public final class CollectionRecreateAction extends CollectionAction { } public void execute() throws HibernateException { - final PersistentCollection collection = getCollection(); + final boolean stats = getSession().getFactory().getStatistics().isStatisticsEnabled(); + long startTime = 0; + if ( stats ) startTime = System.currentTimeMillis(); + + final PersistentCollection collection = getCollection(); getPersister().recreate( collection, getKey(), getSession() ); @@ -31,9 +35,9 @@ public final class CollectionRecreateAction extends CollectionAction { evict(); - if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { + if ( stats ) { getSession().getFactory().getStatisticsImplementor() - .recreateCollection( getPersister().getRole() ); + .recreateCollection( getPersister().getRole(), System.currentTimeMillis() - startTime); } } diff --git a/src/org/hibernate/action/CollectionRemoveAction.java b/src/org/hibernate/action/CollectionRemoveAction.java index 4ea78f5390..e88ff6e445 100644 --- a/src/org/hibernate/action/CollectionRemoveAction.java +++ b/src/org/hibernate/action/CollectionRemoveAction.java @@ -25,7 +25,11 @@ public final class CollectionRemoveAction extends CollectionAction { } public void execute() throws HibernateException { - if ( !emptySnapshot ) getPersister().remove( getKey(), getSession() ); + final boolean stats = getSession().getFactory().getStatistics().isStatisticsEnabled(); + long startTime = 0; + if ( stats ) startTime = System.currentTimeMillis(); + + if ( !emptySnapshot ) getPersister().remove( getKey(), getSession() ); final PersistentCollection collection = getCollection(); if (collection!=null) { @@ -36,9 +40,9 @@ public final class CollectionRemoveAction extends CollectionAction { evict(); - if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { + if ( stats ) { getSession().getFactory().getStatisticsImplementor() - .removeCollection( getPersister().getRole() ); + .removeCollection( getPersister().getRole(), System.currentTimeMillis() - startTime); } } diff --git a/src/org/hibernate/action/CollectionUpdateAction.java b/src/org/hibernate/action/CollectionUpdateAction.java index 91c714f408..6cdf0b5811 100644 --- a/src/org/hibernate/action/CollectionUpdateAction.java +++ b/src/org/hibernate/action/CollectionUpdateAction.java @@ -32,6 +32,9 @@ public final class CollectionUpdateAction extends CollectionAction { final CollectionPersister persister = getPersister(); final PersistentCollection collection = getCollection(); boolean affectedByFilters = persister.isAffectedByEnabledFilters(session); + final boolean stats = session.getFactory().getStatistics().isStatisticsEnabled(); + long startTime = 0; + if ( stats ) startTime = System.currentTimeMillis(); if ( !collection.wasInitialized() ) { if ( !collection.hasQueuedOperations() ) throw new AssertionFailure( "no queued adds" ); @@ -62,9 +65,9 @@ public final class CollectionUpdateAction extends CollectionAction { evict(); - if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { + if ( stats ) { getSession().getFactory().getStatisticsImplementor(). - updateCollection( getPersister().getRole() ); + updateCollection( getPersister().getRole(), System.currentTimeMillis() - startTime); } } diff --git a/src/org/hibernate/action/EntityDeleteAction.java b/src/org/hibernate/action/EntityDeleteAction.java index 50ad219627..529b4203f9 100644 --- a/src/org/hibernate/action/EntityDeleteAction.java +++ b/src/org/hibernate/action/EntityDeleteAction.java @@ -44,6 +44,9 @@ public final class EntityDeleteAction extends EntityAction { EntityPersister persister = getPersister(); SessionImplementor session = getSession(); Object instance = getInstance(); + final boolean stats = session.getFactory().getStatistics().isStatisticsEnabled(); + long startTime = 0; + if ( stats ) startTime = System.currentTimeMillis(); boolean veto = preDelete(); @@ -93,9 +96,9 @@ public final class EntityDeleteAction extends EntityAction { postDelete(); - if ( getSession().getFactory().getStatistics().isStatisticsEnabled() && !veto ) { + if ( stats && !veto ) { getSession().getFactory().getStatisticsImplementor() - .deleteEntity( getPersister().getEntityName() ); + .deleteEntity( getPersister().getEntityName(), System.currentTimeMillis() - startTime); } } diff --git a/src/org/hibernate/action/EntityIdentityInsertAction.java b/src/org/hibernate/action/EntityIdentityInsertAction.java index 59bf5cb054..4e741e98ce 100644 --- a/src/org/hibernate/action/EntityIdentityInsertAction.java +++ b/src/org/hibernate/action/EntityIdentityInsertAction.java @@ -38,7 +38,10 @@ public final class EntityIdentityInsertAction extends EntityAction { final EntityPersister persister = getPersister(); final SessionImplementor session = getSession(); final Object instance = getInstance(); - + final boolean stats = session.getFactory().getStatistics().isStatisticsEnabled(); + long startTime = 0; + if ( stats ) startTime = System.currentTimeMillis(); + boolean veto = preInsert(); // Don't need to lock the cache here, since if someone @@ -65,9 +68,9 @@ public final class EntityIdentityInsertAction extends EntityAction { postInsert(); - if ( session.getFactory().getStatistics().isStatisticsEnabled() && !veto ) { + if ( stats && !veto ) { session.getFactory().getStatisticsImplementor() - .insertEntity( getPersister().getEntityName() ); + .insertEntity( getPersister().getEntityName(), System.currentTimeMillis() - startTime); } } diff --git a/src/org/hibernate/action/EntityInsertAction.java b/src/org/hibernate/action/EntityInsertAction.java index 3c1acdc7d9..2e95d019d9 100644 --- a/src/org/hibernate/action/EntityInsertAction.java +++ b/src/org/hibernate/action/EntityInsertAction.java @@ -46,6 +46,10 @@ public final class EntityInsertAction extends EntityAction { Object instance = getInstance(); Serializable id = getId(); + final boolean stats = session.getFactory().getStatistics().isStatisticsEnabled(); + long startTime = 0; + if ( stats ) startTime = System.currentTimeMillis(); + boolean veto = preInsert(); // Don't need to lock the cache here, since if someone @@ -96,7 +100,7 @@ public final class EntityInsertAction extends EntityAction { // boolean put = persister.getCache().insert(ck, cacheEntry); boolean put = persister.getCache().insert( ck, cacheEntry, version ); - if ( put && factory.getStatistics().isStatisticsEnabled() ) { + if ( put && stats ) { factory.getStatisticsImplementor() .secondLevelCachePut( getPersister().getCache().getRegionName() ); } @@ -105,9 +109,9 @@ public final class EntityInsertAction extends EntityAction { postInsert(); - if ( factory.getStatistics().isStatisticsEnabled() && !veto ) { + if ( stats && !veto ) { factory.getStatisticsImplementor() - .insertEntity( getPersister().getEntityName() ); + .insertEntity( getPersister().getEntityName(), System.currentTimeMillis() - startTime); } } diff --git a/src/org/hibernate/action/EntityUpdateAction.java b/src/org/hibernate/action/EntityUpdateAction.java index 28c8e92b29..f4dffffe90 100644 --- a/src/org/hibernate/action/EntityUpdateAction.java +++ b/src/org/hibernate/action/EntityUpdateAction.java @@ -65,7 +65,11 @@ public final class EntityUpdateAction extends EntityAction { boolean veto = preUpdate(); final SessionFactoryImplementor factory = getSession().getFactory(); - Object previousVersion = this.previousVersion; + final boolean stats = factory.getStatistics().isStatisticsEnabled(); + long startTime = 0; + if ( stats ) startTime = System.currentTimeMillis(); + + Object previousVersion = this.previousVersion; if ( persister.isVersionPropertyGenerated() ) { // we need to grab the version value from the entity, otherwise // we have issues with generated-version entities that may have @@ -158,9 +162,9 @@ public final class EntityUpdateAction extends EntityAction { postUpdate(); - if ( factory.getStatistics().isStatisticsEnabled() && !veto ) { + if ( stats && !veto ) { factory.getStatisticsImplementor() - .updateEntity( getPersister().getEntityName() ); + .updateEntity( getPersister().getEntityName(), System.currentTimeMillis() - startTime); } } diff --git a/src/org/hibernate/cfg/HbmBinder.java b/src/org/hibernate/cfg/HbmBinder.java index 8b1e347a4e..379859b6e7 100644 --- a/src/org/hibernate/cfg/HbmBinder.java +++ b/src/org/hibernate/cfg/HbmBinder.java @@ -1997,7 +1997,7 @@ public final class HbmBinder { Iterator iter = subnode.elementIterator( "param" ); while ( iter.hasNext() ) { Element childNode = (Element) iter.next(); - params.setProperty( childNode.attributeValue( "name" ), childNode.getText() ); + params.setProperty( childNode.attributeValue( "name" ), childNode.getTextTrim() ); } model.setIdentifierGeneratorProperties( params ); diff --git a/src/org/hibernate/criterion/SubqueryExpression.java b/src/org/hibernate/criterion/SubqueryExpression.java index b78fee6b4c..9b5d5c42eb 100755 --- a/src/org/hibernate/criterion/SubqueryExpression.java +++ b/src/org/hibernate/criterion/SubqueryExpression.java @@ -1,17 +1,18 @@ //$Id$ package org.hibernate.criterion; +import java.util.HashMap; + import org.hibernate.Criteria; import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.engine.QueryParameters; import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.TypedValue; import org.hibernate.impl.CriteriaImpl; +import org.hibernate.loader.criteria.CriteriaJoinWalker; import org.hibernate.loader.criteria.CriteriaQueryTranslator; import org.hibernate.persister.entity.OuterJoinLoadable; -import org.hibernate.sql.Select; import org.hibernate.type.Type; /** @@ -24,7 +25,8 @@ public abstract class SubqueryExpression implements Criterion { private String op; private QueryParameters params; private Type[] types; - + private CriteriaQueryTranslator innerQuery; + protected Type[] getTypes() { return types; } @@ -39,34 +41,23 @@ public abstract class SubqueryExpression implements Criterion { public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - - final SessionImplementor session = ( (CriteriaImpl) criteria ).getSession(); //ugly! - final SessionFactoryImplementor factory = session.getFactory(); - + + final SessionFactoryImplementor factory = criteriaQuery.getFactory(); final OuterJoinLoadable persister = (OuterJoinLoadable) factory.getEntityPersister( criteriaImpl.getEntityOrClassName() ); - CriteriaQueryTranslator innerQuery = new CriteriaQueryTranslator( - factory, - criteriaImpl, - criteriaImpl.getEntityOrClassName(), //implicit polymorphism not supported (would need a union) - criteriaQuery.generateSQLAlias(), - criteriaQuery - ); - - params = innerQuery.getQueryParameters(); //TODO: bad lifecycle.... - types = innerQuery.getProjectedTypes(); - - //String filter = persister.filterFragment( innerQuery.getRootSQLALias(), session.getEnabledFilters() ); - - String sql = new Select( factory.getDialect() ) - .setWhereClause( innerQuery.getWhereCondition() ) - .setGroupByClause( innerQuery.getGroupBy() ) - .setSelectClause( innerQuery.getSelect() ) - .setFromClause( - persister.fromTableFragment( innerQuery.getRootSQLALias() ) + - persister.fromJoinFragment( innerQuery.getRootSQLALias(), true, false ) - ) - .toStatementString(); + + createAndSetInnerQuery( criteriaQuery, factory ); + CriteriaJoinWalker walker = new CriteriaJoinWalker( + persister, + innerQuery, + factory, + criteriaImpl, + criteriaImpl.getEntityOrClassName(), + new HashMap(), + innerQuery.getRootSQLALias()); + + String sql = walker.getSQLString(); + final StringBuffer buf = new StringBuffer() .append( toLeftSqlString(criteria, criteriaQuery) ); if (op!=null) buf.append(' ').append(op).append(' '); @@ -77,13 +68,49 @@ public abstract class SubqueryExpression implements Criterion { public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - Type[] types = params.getPositionalParameterTypes(); - Object[] values = params.getPositionalParameterValues(); - TypedValue[] tv = new TypedValue[types.length]; - for ( int i=0; i 0 && operationThreshold < time) { + logOperation(OPERATION_LOAD,entityName, time); + } + } + + public void fetchEntity(String entityName, long time) { + synchronized(this) { + entityFetchCount++; + getEntityStatistics(entityName).fetchCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_FETCH,entityName, time); + } + } /** * find entity statistics per name @@ -165,26 +208,41 @@ public class StatisticsImpl implements Statistics, StatisticsImplementor { } return es; } - - public synchronized void updateEntity(String entityName) { - entityUpdateCount++; - EntityStatistics es = getEntityStatistics(entityName); - es.updateCount++; - } - public synchronized void insertEntity(String entityName) { - entityInsertCount++; - EntityStatistics es = getEntityStatistics(entityName); - es.insertCount++; - } + public void updateEntity(String entityName, long time) { + synchronized(this) { + entityUpdateCount++; + EntityStatistics es = getEntityStatistics(entityName); + es.updateCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_UPDATE,entityName, time); + } + } - public synchronized void deleteEntity(String entityName) { - entityDeleteCount++; - EntityStatistics es = getEntityStatistics(entityName); - es.deleteCount++; - } + public void insertEntity(String entityName, long time) { + synchronized(this) { + entityInsertCount++; + EntityStatistics es = getEntityStatistics(entityName); + es.insertCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_INSERT,entityName, time); + } + } - /** + public void deleteEntity(String entityName, long time) { + synchronized(this) { + entityDeleteCount++; + EntityStatistics es = getEntityStatistics(entityName); + es.deleteCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_DELETE,entityName, time); + } + } + + /** * Get collection statistics per role * * @param role collection role @@ -199,30 +257,55 @@ public class StatisticsImpl implements Statistics, StatisticsImplementor { return cs; } - public synchronized void loadCollection(String role) { - collectionLoadCount++; - getCollectionStatistics(role).loadCount++; - } + public void loadCollection(String role, long time) { + synchronized(this) { + collectionLoadCount++; + getCollectionStatistics(role).loadCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_LOADCOLLECTION,role, time); + } + } - public synchronized void fetchCollection(String role) { - collectionFetchCount++; - getCollectionStatistics(role).fetchCount++; - } + public void fetchCollection(String role, long time) { + synchronized(this) { + collectionFetchCount++; + getCollectionStatistics(role).fetchCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_FETCHCOLLECTION,role, time); + } + } - public synchronized void updateCollection(String role) { - collectionUpdateCount++; - getCollectionStatistics(role).updateCount++; - } + public void updateCollection(String role, long time) { + synchronized(this) { + collectionUpdateCount++; + getCollectionStatistics(role).updateCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_UPDATECOLLECTION,role, time); + } + } - public synchronized void recreateCollection(String role) { - collectionRecreateCount++; - getCollectionStatistics(role).recreateCount++; - } + public void recreateCollection(String role, long time) { + synchronized(this) { + collectionRecreateCount++; + getCollectionStatistics(role).recreateCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_RECREATECOLLECTION,role, time); + } + } - public synchronized void removeCollection(String role) { - collectionRemoveCount++; - getCollectionStatistics(role).removeCount++; - } + public void removeCollection(String role, long time) { + synchronized(this) { + collectionRemoveCount++; + getCollectionStatistics(role).removeCount++; + } + if(operationThreshold > 0 && operationThreshold < time) { + logOperation(OPERATION_REMOVECOLLECTION,role, time); + } + } /** * Second level cache statistics per region @@ -257,17 +340,23 @@ public class StatisticsImpl implements Statistics, StatisticsImplementor { getSecondLevelCacheStatistics(regionName).missCount++; } - public synchronized void queryExecuted(String hql, int rows, long time) { - queryExecutionCount++; - if (queryExecutionMaxTime 0 && operationThreshold < time) { + logOperation(OPERATION_EXECUTEQUERY,hql, time); + } + } public synchronized void queryCacheHit(String hql, String regionName) { queryCacheHitCount++; @@ -556,10 +645,17 @@ public class StatisticsImpl implements Statistics, StatisticsImplementor { } } - public void endTransaction(boolean success) { - transactionCount++; - if (success) commitedTransactionCount++; - } + public void endTransaction(boolean success) { + synchronized(this) { + transactionCount++; + if (success) commitedTransactionCount++; + } + // The end transaction message can get too verbose (output log fills up with just end tx messages) + //if(operationThreshold > 0) { // show endTransaction operations if we are logging operations that exceed a threshold. + // logOperation(OPERATION_ENDTRANSACTION,null, 0); + //} + + } public long getSuccessfulTransactionCount() { return commitedTransactionCount; diff --git a/src/org/hibernate/stat/StatisticsImplementor.java b/src/org/hibernate/stat/StatisticsImplementor.java index 9e08c00fee..c2d9edacdb 100644 --- a/src/org/hibernate/stat/StatisticsImplementor.java +++ b/src/org/hibernate/stat/StatisticsImplementor.java @@ -11,16 +11,16 @@ public interface StatisticsImplementor { public void closeSession(); public void flush(); public void connect(); - public void loadEntity(String entityName); - public void fetchEntity(String entityName); - public void updateEntity(String entityName); - public void insertEntity(String entityName); - public void deleteEntity(String entityName); - public void loadCollection(String role); - public void fetchCollection(String role); - public void updateCollection(String role); - public void recreateCollection(String role); - public void removeCollection(String role); + public void loadEntity(String entityName, long time); + public void fetchEntity(String entityName, long time); + public void updateEntity(String entityName, long time); + public void insertEntity(String entityName, long time); + public void deleteEntity(String entityName, long time); + public void loadCollection(String role, long time); + public void fetchCollection(String role, long time); + public void updateCollection(String role, long time); + public void recreateCollection(String role, long time); + public void removeCollection(String role, long time); public void secondLevelCachePut(String regionName); public void secondLevelCacheHit(String regionName); public void secondLevelCacheMiss(String regionName); diff --git a/test/org/hibernate/test/criteria/CriteriaQueryTest.java b/test/org/hibernate/test/criteria/CriteriaQueryTest.java index ff6ba4fd01..308416f524 100755 --- a/test/org/hibernate/test/criteria/CriteriaQueryTest.java +++ b/test/org/hibernate/test/criteria/CriteriaQueryTest.java @@ -16,7 +16,6 @@ import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Example; -import org.hibernate.criterion.Expression; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projection; @@ -154,8 +153,8 @@ public class CriteriaQueryTest extends FunctionalTestCase { .list(); session.createCriteria(Student.class) - .add( Property.forName("name").eqAll(dc) ) - .list(); + .add( Property.forName("name").eqAll(dc) ) + .list(); session.createCriteria(Student.class) .add( Subqueries.in("Gavin King", dc) ) @@ -169,8 +168,7 @@ public class CriteriaQueryTest extends FunctionalTestCase { .add( Subqueries.eq("Gavin King", dc2) ) .list(); - //TODO: join in subselect: HHH-952 - /*DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st") + DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st") .createCriteria("enrolments") .createCriteria("course") .add( Property.forName("description").eq("Hibernate Training") ) @@ -178,7 +176,7 @@ public class CriteriaQueryTest extends FunctionalTestCase { session.createCriteria(Enrolment.class, "e") .add( Subqueries.eq("Gavin King", dc3) ) - .list();*/ + .list(); session.delete(enrolment2); session.delete(gavin); @@ -398,8 +396,8 @@ public class CriteriaQueryTest extends FunctionalTestCase { .add( Projections.property("studentNumber"), "stNumber" ) .add( Projections.property("courseCode"), "cCode" ) ) ) - .add( Expression.gt( "studentNumber", new Long(665) ) ) - .add( Expression.lt( "studentNumber", new Long(668) ) ) + .add( Restrictions.gt( "studentNumber", new Long(665) ) ) + .add( Restrictions.lt( "studentNumber", new Long(668) ) ) .addOrder( Order.asc("stNumber") ) .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP) .list(); diff --git a/test/org/hibernate/test/discriminator/DiscriminatorTest.java b/test/org/hibernate/test/discriminator/DiscriminatorTest.java index 583297c63b..94fe5a4cc1 100755 --- a/test/org/hibernate/test/discriminator/DiscriminatorTest.java +++ b/test/org/hibernate/test/discriminator/DiscriminatorTest.java @@ -10,7 +10,9 @@ import junit.framework.Test; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; +import org.hibernate.proxy.HibernateProxy; import org.hibernate.criterion.Property; +import org.hibernate.criterion.Restrictions; import org.hibernate.junit.functional.FunctionalTestCase; import org.hibernate.junit.functional.FunctionalTestClassTestSuite; @@ -171,6 +173,82 @@ public class DiscriminatorTest extends FunctionalTestCase { s.close(); } + public void testLoadSuperclassProxyPolymorphicAccess() { + 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(); + // load the superclass proxy. + Person pLoad = ( Person ) s.load( Person.class, new Long( e.getId() ) ); + assertTrue( pLoad instanceof HibernateProxy); + Person pGet = ( Person ) s.get( Person.class, new Long( e.getId() )); + Person pQuery = ( Person ) s.createQuery( "from Person where id = :id" ) + .setLong( "id", e.getId() ) + .uniqueResult(); + Person pCriteria = ( Person ) s.createCriteria( Person.class ) + .add( Restrictions.idEq( new Long( e.getId() ) ) ) + .uniqueResult(); + // assert that executing the queries polymorphically returns the same proxy + assertSame( pLoad, pGet ); + assertSame( pLoad, pQuery ); + assertSame( pLoad, pCriteria ); + + // assert that the proxy is not an instance of Employee + assertFalse( pLoad instanceof Employee ); + + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.delete( e ); + s.getTransaction().commit(); + s.close(); + } + + public void testLoadSuperclassProxyEvictPolymorphicAccess() { + 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(); + // load the superclass proxy. + Person pLoad = ( Person ) s.load( Person.class, new Long( e.getId() ) ); + assertTrue( pLoad instanceof HibernateProxy); + // evict the proxy + s.evict( pLoad ); + Employee pGet = ( Employee ) s.get( Person.class, new Long( e.getId() )); + Employee pQuery = ( Employee ) s.createQuery( "from Person where id = :id" ) + .setLong( "id", e.getId() ) + .uniqueResult(); + Employee pCriteria = ( Employee ) s.createCriteria( Person.class ) + .add( Restrictions.idEq( new Long( e.getId() ) ) ) + .uniqueResult(); + // assert that executing the queries polymorphically returns the same Employee instance + assertSame( pGet, pQuery ); + assertSame( pGet, pCriteria ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.delete( e ); + s.getTransaction().commit(); + s.close(); + } } - diff --git a/test/org/hibernate/test/hql/BulkManipulationTest.java b/test/org/hibernate/test/hql/BulkManipulationTest.java index 119fdcaa1e..276b62f389 100644 --- a/test/org/hibernate/test/hql/BulkManipulationTest.java +++ b/test/org/hibernate/test/hql/BulkManipulationTest.java @@ -451,6 +451,17 @@ public class BulkManipulationTest extends FunctionalTestCase { s.close(); } + public void testInsertWithSelectListUsingJoins() { + // this is just checking parsing and syntax... + Session s = openSession(); + s.beginTransaction(); + s.createQuery( "insert into Animal (description, bodyWeight) select h.description, h.bodyWeight from Human h where h.mother.mother is not null" ).executeUpdate(); + s.createQuery( "delete from Animal" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } + + // UPDATES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public void testIncorrectSyntax() { diff --git a/test/org/hibernate/test/ops/MergeTest.java b/test/org/hibernate/test/ops/MergeTest.java index 3862e94bc9..1a86c05c40 100755 --- a/test/org/hibernate/test/ops/MergeTest.java +++ b/test/org/hibernate/test/ops/MergeTest.java @@ -8,11 +8,12 @@ import java.util.List; import junit.framework.Test; import org.hibernate.Hibernate; -import org.hibernate.Session; -import org.hibernate.Transaction; import org.hibernate.NonUniqueObjectException; -import org.hibernate.junit.functional.FunctionalTestClassTestSuite; +import org.hibernate.Session; +import org.hibernate.StaleObjectStateException; +import org.hibernate.Transaction; import org.hibernate.criterion.Projections; +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; /** * @author Gavin King @@ -27,6 +28,39 @@ public class MergeTest extends AbstractOperationTestCase { return new FunctionalTestClassTestSuite( MergeTest.class ); } + public void testMergeStaleVersionFails() throws Exception { + Session s = openSession(); + s.beginTransaction(); + VersionedEntity entity = new VersionedEntity( "entity", "entity" ); + s.persist( entity ); + s.getTransaction().commit(); + s.close(); + + // make the detached 'entity' reference stale... + s = openSession(); + s.beginTransaction(); + VersionedEntity entity2 = ( VersionedEntity ) s.get( VersionedEntity.class, entity.getId() ); + entity2.setName( "entity-name" ); + s.getTransaction().commit(); + s.close(); + + // now try to reattch it + s = openSession(); + s.beginTransaction(); + try { + s.merge( entity ); + s.getTransaction().commit(); + fail( "was expecting staleness error" ); + } + catch ( StaleObjectStateException expected ) { + // expected outcome... + } + finally { + s.getTransaction().rollback(); + s.close(); + } + } + public void testMergeBidiPrimayKeyOneToOne() throws Exception { Session s = openSession(); s.beginTransaction(); @@ -121,7 +155,7 @@ public class MergeTest extends AbstractOperationTestCase { assertInsertCount( 0 ); /////////////////////////////////////////////////////////////////////// - cleanup(); +// cleanup(); } public void testNoExtraUpdatesOnMergeWithCollection() throws Exception { @@ -162,7 +196,7 @@ public class MergeTest extends AbstractOperationTestCase { assertInsertCount( 1 ); /////////////////////////////////////////////////////////////////////// - cleanup(); +// cleanup(); } public void testNoExtraUpdatesOnMergeVersioned() throws Exception { @@ -201,7 +235,7 @@ public class MergeTest extends AbstractOperationTestCase { assertInsertCount( 0 ); /////////////////////////////////////////////////////////////////////// - cleanup(); +// cleanup(); } public void testNoExtraUpdatesOnMergeVersionedWithCollection() throws Exception { @@ -245,7 +279,7 @@ public class MergeTest extends AbstractOperationTestCase { assertInsertCount( 1 ); /////////////////////////////////////////////////////////////////////// - cleanup(); +// cleanup(); } public void testPersistThenMergeInSameTxnWithVersion() { @@ -267,7 +301,7 @@ public class MergeTest extends AbstractOperationTestCase { tx.commit(); s.close(); - cleanup(); +// cleanup(); } public void testPersistThenMergeInSameTxnWithTimestamp() { @@ -289,7 +323,7 @@ public class MergeTest extends AbstractOperationTestCase { tx.commit(); s.close(); - cleanup(); +// cleanup(); } public void testMergeDeepTree() { @@ -447,7 +481,7 @@ public class MergeTest extends AbstractOperationTestCase { assertInsertCount(1); assertUpdateCount(2); - cleanup(); +// cleanup(); } public void testMergeTreeWithGeneratedId() { @@ -482,7 +516,7 @@ public class MergeTest extends AbstractOperationTestCase { assertInsertCount(1); assertUpdateCount(2); - cleanup(); +// cleanup(); } public void testMergeManaged() { @@ -524,7 +558,7 @@ public class MergeTest extends AbstractOperationTestCase { s.close(); - cleanup(); +// cleanup(); } public void testRecursiveMergeTransient() { @@ -544,7 +578,7 @@ public class MergeTest extends AbstractOperationTestCase { tx.commit(); s.close(); - cleanup(); +// cleanup(); } public void testDeleteAndMerge() throws Exception { @@ -567,7 +601,7 @@ public class MergeTest extends AbstractOperationTestCase { s.getTransaction().commit(); s.close(); - cleanup(); +// cleanup(); } public void testMergeManyToManyWithCollectionDeference() throws Exception { @@ -610,11 +644,16 @@ public class MergeTest extends AbstractOperationTestCase { tx.commit(); s.close(); +// cleanup(); + } + + protected void cleanupTest() throws Exception { cleanup(); + super.cleanupTest(); } private void cleanup() { - Session s = openSession(); + Session s = sfi().openSession(); s.beginTransaction(); s.createQuery( "delete from NumberedNode where parent is not null" ).executeUpdate(); s.createQuery( "delete from NumberedNode" ).executeUpdate();