From: <hib...@li...> - 2006-03-28 20:00:17
|
Author: ste...@jb... Date: 2006-03-28 15:00:04 -0500 (Tue, 28 Mar 2006) New Revision: 9706 Modified: branches/Branch_3_1/Hibernate3/src/org/hibernate/StatelessSession.java branches/Branch_3_1/Hibernate3/src/org/hibernate/impl/StatelessSessionImpl.java branches/Branch_3_1/Hibernate3/test/org/hibernate/test/stateless/StatelessSessionTest.java Log: HHH-1266 : StatelessSession.refresh() Modified: branches/Branch_3_1/Hibernate3/src/org/hibernate/StatelessSession.java =================================================================== --- branches/Branch_3_1/Hibernate3/src/org/hibernate/StatelessSession.java 2006-03-28 19:59:31 UTC (rev 9705) +++ branches/Branch_3_1/Hibernate3/src/org/hibernate/StatelessSession.java 2006-03-28 20:00:04 UTC (rev 9706) @@ -27,67 +27,125 @@ * Close the stateless session and release the JDBC connection. */ public void close(); + /** * Insert a row. + * * @param entity a new transient instance */ public Serializable insert(Object entity); + /** - * Update a row. - * @param entity a detached entity instance - */ - public void update(Object entity); - /** - * Delete a row. - * @param entity a detached entity instance - */ - public void delete(Object entity); - /** * Insert a row. + * + * @param entityName The entityName for the entity to be inserted * @param entity a new transient instance * @return the identifier of the instance */ public Serializable insert(String entityName, Object entity); + /** * Update a row. + * * @param entity a detached entity instance */ + public void update(Object entity); + + /** + * Update a row. + * + * @param entityName The entityName for the entity to be updated + * @param entity a detached entity instance + */ public void update(String entityName, Object entity); + /** * Delete a row. + * * @param entity a detached entity instance */ + public void delete(Object entity); + + /** + * Delete a row. + * + * @param entityName The entityName for the entity to be deleted + * @param entity a detached entity instance + */ public void delete(String entityName, Object entity); + /** * Retrieve a row. + * * @return a detached entity instance */ public Object get(String entityName, Serializable id); + /** * Retrieve a row. + * * @return a detached entity instance */ public Object get(Class entityClass, Serializable id); + /** * Retrieve a row, obtaining the specified lock mode. + * * @return a detached entity instance */ public Object get(String entityName, Serializable id, LockMode lockMode); + /** * Retrieve a row, obtaining the specified lock mode. + * * @return a detached entity instance */ public Object get(Class entityClass, Serializable id, LockMode lockMode); + /** + * Refresh the entity instance state from the database. + * + * @param entity The entity to be refreshed. + */ + public void refresh(Object entity); + + /** + * Refresh the entity instance state from the database. + * + * @param entityName The entityName for the entity to be refreshed. + * @param entity The entity to be refreshed. + */ + public void refresh(String entityName, Object entity); + + /** + * Refresh the entity instance state from the database. + * + * @param entity The entity to be refreshed. + * @param lockMode The LockMode to be applied. + */ + public void refresh(Object entity, LockMode lockMode); + + /** + * Refresh the entity instance state from the database. + * + * @param entityName The entityName for the entity to be refreshed. + * @param entity The entity to be refreshed. + * @param lockMode The LockMode to be applied. + */ + public void refresh(String entityName, Object entity, LockMode lockMode); + + /** * Create a new instance of <tt>Query</tt> for the given HQL query string. * Entities returned by the query are detached. */ public Query createQuery(String queryString); + /** * Obtain an instance of <tt>Query</tt> for a named query string defined in * the mapping file. Entities returned by the query are detached. */ public Query getNamedQuery(String queryName); + /** * Create a new <tt>Criteria</tt> instance, for the given entity class, * or a superclass of an entity class. Entities returned by the query are @@ -97,6 +155,7 @@ * @return Criteria */ public Criteria createCriteria(Class persistentClass); + /** * Create a new <tt>Criteria</tt> instance, for the given entity class, * or a superclass of an entity class, with the given alias. @@ -106,6 +165,7 @@ * @return Criteria */ public Criteria createCriteria(Class persistentClass, String alias); + /** * Create a new <tt>Criteria</tt> instance, for the given entity name. * Entities returned by the query are detached. @@ -114,6 +174,7 @@ * @return Criteria */ public Criteria createCriteria(String entityName); + /** * Create a new <tt>Criteria</tt> instance, for the given entity name, * with the given alias. Entities returned by the query are detached. @@ -122,6 +183,7 @@ * @return Criteria */ public Criteria createCriteria(String entityName, String alias); + /** * Create a new instance of <tt>SQLQuery</tt> for the given SQL query string. * Entities returned by the query are detached. @@ -131,19 +193,22 @@ * @throws HibernateException */ public SQLQuery createSQLQuery(String queryString) throws HibernateException; + /** * Begin a Hibernate transaction. */ public Transaction beginTransaction(); + /** * Get the current Hibernate transaction. */ public Transaction getTransaction(); + /** * Returns the current JDBC connection associated with this * instance.<br> * <br> - * If the session is using aggressive collection release (as in a + * If the session is using aggressive connection release (as in a * CMT environment), it is the application's responsibility to * close the connection returned by this call. Otherwise, the * application should not close the connection. Modified: branches/Branch_3_1/Hibernate3/src/org/hibernate/impl/StatelessSessionImpl.java =================================================================== --- branches/Branch_3_1/Hibernate3/src/org/hibernate/impl/StatelessSessionImpl.java 2006-03-28 19:59:31 UTC (rev 9705) +++ branches/Branch_3_1/Hibernate3/src/org/hibernate/impl/StatelessSessionImpl.java 2006-03-28 20:00:04 UTC (rev 9706) @@ -4,7 +4,6 @@ import java.io.Serializable; import java.sql.Connection; import java.util.Collections; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -25,6 +24,9 @@ import org.hibernate.SessionException; import org.hibernate.StatelessSession; import org.hibernate.Transaction; +import org.hibernate.UnresolvableObjectException; +import org.hibernate.cache.CacheKey; +import org.hibernate.pretty.MessageHelper; import org.hibernate.collection.PersistentCollection; import org.hibernate.engine.EntityKey; import org.hibernate.engine.PersistenceContext; @@ -44,46 +46,33 @@ import org.hibernate.proxy.HibernateProxy; import org.hibernate.type.Type; import org.hibernate.util.CollectionHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * @author Gavin King */ public class StatelessSessionImpl extends AbstractSessionImpl implements JDBCContext.Context, StatelessSession { - + + private static final Log log = LogFactory.getLog( StatelessSessionImpl.class ); + private JDBCContext jdbcContext; - - StatelessSessionImpl( - Connection connection, - SessionFactoryImpl factory - ) { - super(factory); + private PersistenceContext temporaryPersistenceContext = new StatefulPersistenceContext( this ); + + StatelessSessionImpl(Connection connection, SessionFactoryImpl factory) { + super( factory ); this.jdbcContext = new JDBCContext( this, connection, EmptyInterceptor.INSTANCE ); } - public boolean isOpen() { - return !isClosed(); - } - public void close() { - managedClose(); - } - - public void delete(Object entity) { - errorIfClosed(); - delete(null, entity); - } + // inserts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public Serializable insert(Object entity) { errorIfClosed(); return insert(null, entity); } - public void update(Object entity) { - errorIfClosed(); - update(null, entity); - } - public Serializable insert(String entityName, Object entity) { errorIfClosed(); EntityPersister persister = getEntityPersister(entityName, entity); @@ -91,18 +80,44 @@ Object[] state = persister.getPropertyValues(entity, EntityMode.POJO); if ( persister.isVersioned() ) { boolean substitute = Versioning.seedVersion(state, persister.getVersionProperty(), persister.getVersionType(), this); - if (substitute) persister.setPropertyValues(entity, state, EntityMode.POJO); + if ( substitute ) { + persister.setPropertyValues( entity, state, EntityMode.POJO ); + } } if ( id == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) { id = persister.insert(state, entity, this); } else { - persister.insert(id, state, entity, this); + persister.insert(id, state, entity, this); } persister.setIdentifier(entity, id, EntityMode.POJO); return id; } - + + + // deletes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public void delete(Object entity) { + errorIfClosed(); + delete(null, entity); + } + + public void delete(String entityName, Object entity) { + errorIfClosed(); + EntityPersister persister = getEntityPersister(entityName, entity); + Serializable id = persister.getIdentifier(entity, EntityMode.POJO); + Object version = persister.getVersion(entity, EntityMode.POJO); + persister.delete(id, version, entity, this); + } + + + // updates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public void update(Object entity) { + errorIfClosed(); + update(null, entity); + } + public void update(String entityName, Object entity) { errorIfClosed(); EntityPersister persister = getEntityPersister(entityName, entity); @@ -120,15 +135,141 @@ } persister.update(id, state, null, false, null, oldVersion, entity, null, this); } - - public void delete(String entityName, Object entity) { + + + // loading ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public Object get(Class entityClass, Serializable id) { + return get( entityClass.getName(), id ); + } + + public Object get(Class entityClass, Serializable id, LockMode lockMode) { + return get( entityClass.getName(), id, lockMode ); + } + + public Object get(String entityName, Serializable id) { + return get(entityName, id, LockMode.NONE); + } + + public Object get(String entityName, Serializable id, LockMode lockMode) { errorIfClosed(); - EntityPersister persister = getEntityPersister(entityName, entity); - Serializable id = persister.getIdentifier(entity, EntityMode.POJO); - Object version = persister.getVersion(entity, EntityMode.POJO); - persister.delete(id, version, entity, this); + Object result = getFactory().getEntityPersister(entityName) + .load(id, null, lockMode, this); + temporaryPersistenceContext.clear(); + return result; } + public void refresh(Object entity) { + refresh( bestGuessEntityName( entity ), entity, LockMode.NONE ); + } + + public void refresh(String entityName, Object entity) { + refresh( entityName, entity, LockMode.NONE ); + } + + public void refresh(Object entity, LockMode lockMode) { + refresh( bestGuessEntityName( entity ), entity, lockMode ); + } + + public void refresh(String entityName, Object entity, LockMode lockMode) { + final EntityPersister persister = this.getEntityPersister( entityName, entity ); + final Serializable id = persister.getIdentifier( entity, getEntityMode() ); + if ( log.isTraceEnabled() ) { + log.trace( + "refreshing transient " + + MessageHelper.infoString( persister, id, this.getFactory() ) + ); + } + // TODO : can this ever happen??? +// EntityKey key = new EntityKey( id, persister, source.getEntityMode() ); +// if ( source.getPersistenceContext().getEntry( key ) != null ) { +// throw new PersistentObjectException( +// "attempted to refresh transient instance when persistent " + +// "instance was already associated with the Session: " + +// MessageHelper.infoString( persister, id, source.getFactory() ) +// ); +// } + + if ( persister.hasCache() ) { + final CacheKey ck = new CacheKey( + id, + persister.getIdentifierType(), + persister.getRootEntityName(), + this.getEntityMode(), + this.getFactory() + ); + persister.getCache().remove(ck); + } + + String previousFetchProfile = this.getFetchProfile(); + Object result = null; + try { + this.setFetchProfile( "refresh" ); + result = persister.load( id, entity, lockMode, this ); + } + finally { + this.setFetchProfile( previousFetchProfile ); + } + UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() ); + } + + public Object immediateLoad(String entityName, Serializable id) + throws HibernateException { + throw new SessionException("proxies cannot be fetched by a stateless session"); + } + + public void initializeCollection( + PersistentCollection collection, + boolean writing) throws HibernateException { + throw new SessionException("collections cannot be fetched by a stateless session"); + } + + public Object instantiate( + String entityName, + Serializable id) throws HibernateException { + errorIfClosed(); + return getFactory().getEntityPersister( entityName ) + .instantiate( id, EntityMode.POJO ); + } + + public Object internalLoad( + String entityName, + Serializable id, + boolean eager, + boolean nullable) throws HibernateException { + errorIfClosed(); + EntityPersister persister = getFactory().getEntityPersister(entityName); + if ( !eager && persister.hasProxy() ) { + return persister.createProxy(id, this); + } + Object loaded = temporaryPersistenceContext.getEntity( new EntityKey(id, persister, EntityMode.POJO) ); + //TODO: if not loaded, throw an exception + return loaded==null ? get(entityName, id) : loaded; + } + + public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException { + throw new UnsupportedOperationException(); + } + + public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) + throws HibernateException { + throw new UnsupportedOperationException(); + } + + public List listFilter(Object collection, String filter, QueryParameters queryParameters) + throws HibernateException { + throw new UnsupportedOperationException(); + } + + + public boolean isOpen() { + return !isClosed(); + } + + public void close() { + managedClose(); + } + public ConnectionReleaseMode getConnectionReleaseMode() { return factory.getSettings().getConnectionReleaseMode(); } @@ -178,8 +319,8 @@ return jdbcContext.borrowConnection(); } - public int executeUpdate(String query, QueryParameters queryParameters) - throws HibernateException { + public int executeUpdate(String query, QueryParameters queryParameters) + throws HibernateException { errorIfClosed(); queryParameters.validateParameters(); HQLQueryPlan plan = getHQLQueryPlan( query, false ); @@ -223,11 +364,11 @@ return EntityMode.POJO; } - public EntityPersister getEntityPersister(String entityName, Object object) - throws HibernateException { + public EntityPersister getEntityPersister(String entityName, Object object) + throws HibernateException { errorIfClosed(); - if (entityName==null) { - return factory.getEntityPersister( guessEntityName(object) ); + if ( entityName==null ) { + return factory.getEntityPersister( guessEntityName( object ) ); } else { return factory.getEntityPersister( entityName ) @@ -267,60 +408,13 @@ public long getTimestamp() { throw new UnsupportedOperationException(); } - - private PersistenceContext temporaryPersistenceContext = new StatefulPersistenceContext(this); - - public Object get(Class entityClass, Serializable id) { - return get( entityClass.getName(), id ); - } - - public Object get(Class entityClass, Serializable id, LockMode lockMode) { - return get( entityClass.getName(), id, lockMode ); - } - - public Object get(String entityName, Serializable id) { - return get(entityName, id, LockMode.NONE); - } - public Object get(String entityName, Serializable id, LockMode lockMode) { - errorIfClosed(); - Object result = getFactory().getEntityPersister(entityName) - .load(id, null, lockMode, this); - temporaryPersistenceContext.clear(); - return result; - } - public String guessEntityName(Object entity) throws HibernateException { errorIfClosed(); return entity.getClass().getName(); } - public Object immediateLoad(String entityName, Serializable id) throws HibernateException { - throw new SessionException("proxies cannot be fetched by a stateless session"); - } - public void initializeCollection(PersistentCollection collection, boolean writing) - throws HibernateException { - throw new SessionException("collections cannot be fetched by a stateless session"); - } - - public Object instantiate(String entityName, Serializable id) throws HibernateException { - errorIfClosed(); - return getFactory().getEntityPersister(entityName).instantiate(id, EntityMode.POJO); - } - - public Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable) - throws HibernateException { - errorIfClosed(); - EntityPersister persister = getFactory().getEntityPersister(entityName); - if ( !eager && persister.hasProxy() ) { - return persister.createProxy(id, this); - } - Object loaded = temporaryPersistenceContext.getEntity( new EntityKey(id, persister, EntityMode.POJO) ); - //TODO: if not loaded, throw an exception - return loaded==null ? get(entityName, id) : loaded; - } - public boolean isConnected() { return jdbcContext.getConnectionManager().isCurrentlyConnected(); } @@ -329,20 +423,6 @@ return jdbcContext.isTransactionInProgress(); } - public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException { - throw new UnsupportedOperationException(); - } - - public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) - throws HibernateException { - throw new UnsupportedOperationException(); - } - - public List listFilter(Object collection, String filter, QueryParameters queryParameters) - throws HibernateException { - throw new UnsupportedOperationException(); - } - public void setAutoClear(boolean enabled) { throw new UnsupportedOperationException(); } @@ -354,25 +434,25 @@ public void setFlushMode(FlushMode fm) { throw new UnsupportedOperationException(); } - + public Transaction getTransaction() throws HibernateException { errorIfClosed(); return jdbcContext.getTransaction(); } - + public Transaction beginTransaction() throws HibernateException { errorIfClosed(); Transaction result = getTransaction(); result.begin(); return result; } - + public boolean isEventSource() { return false; } - + ///////////////////////////////////////////////////////////////////////////////////////////////////// - + //TODO: COPY/PASTE FROM SessionImpl, pull up! public List list(String query, QueryParameters queryParameters) throws HibernateException { @@ -423,9 +503,9 @@ String entityName = criteria.getEntityOrClassName(); CriteriaLoader loader = new CriteriaLoader( getOuterJoinLoadable(entityName), - factory, - criteria, - entityName, + factory, + criteria, + entityName, getEnabledFilters() ); return loader.scroll(this, scrollMode); @@ -437,22 +517,16 @@ int size = implementors.length; CriteriaLoader[] loaders = new CriteriaLoader[size]; - Set spaces = new HashSet(); for( int i=0; i <size; i++ ) { - loaders[i] = new CriteriaLoader( getOuterJoinLoadable( implementors[i] ), - factory, - criteria, - implementors[i], + factory, + criteria, + implementors[i], getEnabledFilters() ); - - spaces.addAll( loaders[i].getQuerySpaces() ); - } - List results = Collections.EMPTY_LIST; boolean success = false; try { @@ -478,7 +552,7 @@ return ( OuterJoinLoadable ) persister; } - public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) + public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) throws HibernateException { errorIfClosed(); CustomLoader loader = new CustomLoader( customQuery, getFactory() ); @@ -496,7 +570,7 @@ return results; } - public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) + public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) throws HibernateException { errorIfClosed(); CustomLoader loader = new CustomLoader( customQuery, getFactory() ); Modified: branches/Branch_3_1/Hibernate3/test/org/hibernate/test/stateless/StatelessSessionTest.java =================================================================== --- branches/Branch_3_1/Hibernate3/test/org/hibernate/test/stateless/StatelessSessionTest.java 2006-03-28 19:59:31 UTC (rev 9705) +++ branches/Branch_3_1/Hibernate3/test/org/hibernate/test/stateless/StatelessSessionTest.java 2006-03-28 20:00:04 UTC (rev 9706) @@ -129,7 +129,33 @@ ss.close(); } - + public void testRefresh() { + StatelessSession ss = getSessions().openStatelessSession(); + Transaction tx = ss.beginTransaction(); + Paper paper = new Paper(); + paper.setColor( "whtie" ); + ss.insert( paper ); + tx.commit(); + ss.close(); + + ss = getSessions().openStatelessSession(); + tx = ss.beginTransaction(); + Paper p2 = ( Paper ) ss.get( Paper.class, paper.getId() ); + p2.setColor( "White" ); + ss.update( p2 ); + tx.commit(); + ss.close(); + + ss = getSessions().openStatelessSession(); + tx = ss.beginTransaction(); + assertEquals( "whtie", paper.getColor() ); + ss.refresh( paper ); + assertEquals( "White", paper.getColor() ); + ss.delete( paper ); + tx.commit(); + ss.close(); + } + protected String[] getMappings() { return new String[] { "stateless/Document.hbm.xml" }; } |