testcase.java

来自「好东西,hibernate-3.2.0,他是一开元的树杖hibernate-3.」· Java 代码 · 共 560 行 · 第 1/2 页

JAVA
560
字号
//$Id: TestCase.java 10424 2006-09-01 21:36:13Z steve.ebersole@jboss.com $
package org.hibernate.test;

import java.sql.Blob;
import java.sql.Clob;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import junit.framework.AssertionFailedError;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle9Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.TimesTenDialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue;

public abstract class TestCase extends junit.framework.TestCase {

	private static SessionFactory sessions;
	private static Configuration cfg;
	private static Dialect dialect;
	private static Class lastTestClass;
	private org.hibernate.classic.Session session;

	public TestCase(String name) {
		super( name );
	}


	// methods for subclasses to change test environment ~~~~~~~~~~~~~~~~~~~~~~

	/**
	 * Get the mapping resources to be used to build the configuration.
	 * <p/>
	 * Resources should be relative to {@link #getBaseForMappings()}
	 *
	 * @return The mapping resources
	 */
	protected abstract String[] getMappings();

	/**
	 * The base name for relative mapping resources.  The default is
	 * <tt>org/hibernate/test/</tt>
	 *
	 * @return the mapping resource base
	 */
	protected String getBaseForMappings() {
		return "org/hibernate/test/";
	}

	/**
	 * Should the database schema be (re)created
	 *
	 * @return True for auto export (including recreation on test failure).
	 */
	protected boolean recreateSchema() {
		return true;
	}

	protected boolean dropAfterFailure() {
		return true;
	}

	/**
	 * Apply any test-specific configuration prior to building the factory.
	 *
	 * @param cfg The configuration which will be used to construct the factory.
	 */
	protected void configure(Configuration cfg) {
	}

	protected boolean overrideCacheStrategy() {
		return true;
	}

	protected String getCacheConcurrencyStrategy() {
		return "nonstrict-read-write";
	}


	// methods for subclasses to access environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~

	/**
	 * Get the factory for this test environment.
	 *
	 * @return The factory.
	 */
	protected SessionFactory getSessions() {
		return sessions;
	}

	/**
	 * Get the factory for this test environment, casted to {@link SessionFactoryImplementor}.
	 * <p/>
	 * Shorthand for ( {@link SessionFactoryImplementor} ) {@link #getSessions()}...
	 *
	 * @return The factory
	 */
	protected SessionFactoryImplementor sfi() {
		return ( SessionFactoryImplementor ) getSessions();
	}

	protected Dialect getDialect() {
		return dialect;
	}

	protected Configuration getCfg() {
		return cfg;
	}

	public org.hibernate.classic.Session openSession() throws HibernateException {
		session = getSessions().openSession();
		return session;
	}

	public org.hibernate.classic.Session openSession(Interceptor interceptor)
	throws HibernateException {
		session = getSessions().openSession(interceptor);
		return session;
	}


	// JUnit hooks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	/**
	 * The Hibernate test suite tries to only build the db schema once
	 * per test class (not test case which = instance) hence all the
	 * static vars.
	 * <p/>
	 * Here is the crux of that attempt.  We only build a factory when one was
	 * not previously built, or when we start a new test class.
	 *
	 * @throws Exception
	 */
	protected void setUp() throws Exception {
		if ( getSessions() == null || lastTestClass != getClass() ) {
			buildSessionFactory();
			lastTestClass = getClass();
		}
	}


	private void buildSessionFactory() throws Exception {
		if ( getSessions()!=null ) {
			getSessions().close();
		}

		TestCase.dialect = Dialect.getDialect();
		if ( ! appliesTo( getDialect() ) ) {
			return;
		}

		try {

			TestCase.cfg = new Configuration();
			cfg.setProperty( Environment.CACHE_PROVIDER, "org.hibernate.cache.HashtableCacheProvider" );
			if( recreateSchema() ) {
				cfg.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
			}
			addMappings( getMappings(), cfg );
			configure( cfg );

			if ( getCacheConcurrencyStrategy() != null ) {
				Iterator iter = cfg.getClassMappings();
				while ( iter.hasNext() ) {
					PersistentClass clazz = (PersistentClass) iter.next();
					Iterator props = clazz.getPropertyClosureIterator();
					boolean hasLob = false;
					while ( props.hasNext() ) {
						Property prop = (Property) props.next();
						if ( prop.getValue().isSimpleValue() ) {
							String type = ( (SimpleValue) prop.getValue() ).getTypeName();
							if ( "blob".equals( type ) || "clob".equals( type ) ) {
								hasLob = true;
							}
							if ( Blob.class.getName().equals( type ) || Clob.class.getName().equals( type ) ) {
								hasLob = true;
							}
						}
					}
					if ( !hasLob && !clazz.isInherited() && overrideCacheStrategy() ) {
						cfg.setCacheConcurrencyStrategy(
								clazz.getEntityName(),
								getCacheConcurrencyStrategy()
							);
					}
				}
				iter = cfg.getCollectionMappings();
				while ( iter.hasNext() ) {
					Collection coll = (Collection) iter.next();
					cfg.setCollectionCacheConcurrencyStrategy(
							coll.getRole(),
							getCacheConcurrencyStrategy()
						);
				}
			}

			// make sure we use the same dialect...
			cfg.setProperty( Environment.DIALECT, TestCase.dialect.getClass().getName() );
			TestCase.sessions = cfg.buildSessionFactory();
			afterSessionFactoryBuilt();
		}
		catch ( Exception e ) {
			e.printStackTrace();
			throw e;
		}
	}

	protected void addMappings(String[] files, Configuration cfg) {
		for ( int i = 0; i < files.length; i++ ) {
			if ( !files[i].startsWith( "net/" ) ) {
				files[i] = getBaseForMappings() + files[i];
			}
			cfg.addResource( files[i], TestCase.class.getClassLoader() );
		}
	}

	protected void afterSessionFactoryBuilt() throws Exception {
		// for subclasses to override in order to perform extra "stuff" only
		// when SF (re)built...
	}

	protected void runTest() throws Throwable {
		final boolean stats = sessions.getStatistics().isStatisticsEnabled();
		try {
			if ( stats ) {
				sessions.getStatistics().clear();
			}

			super.runTest();

			if ( stats ) {
				sessions.getStatistics().logSummary();
			}

			if ( session != null && session.isOpen() ) {
				if ( session.isConnected() ) {
					session.connection().rollback();
				}
				session.close();
				session = null;
				fail( "unclosed session" );
			}
			else {
				session = null;
			}
			assertAllDataRemoved();
		}
		catch ( Throwable e ) {
			try {
				if ( session != null && session.isOpen() ) {
					if ( session.isConnected() ) {
						session.connection().rollback();
					}
					session.close();
				}
			}
			catch ( Exception ignore ) {
			}
			try {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?