⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 normalizedentitypersister.java

📁 用Java实现的23个常用设计模式源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
//$Id: NormalizedEntityPersister.java,v 1.32.2.37 2003/11/29 06:52:55 oneovthafew Exp $package net.sf.hibernate.persister;import net.sf.hibernate.util.ArrayHelper;import net.sf.hibernate.util.JDBCExceptionReporter;import net.sf.hibernate.util.StringHelper;import net.sf.hibernate.loader.UniqueEntityLoader;import net.sf.hibernate.mapping.Column;import net.sf.hibernate.mapping.PersistentClass;import net.sf.hibernate.mapping.Property;import net.sf.hibernate.mapping.Subclass;import net.sf.hibernate.mapping.Table;import java.io.Serializable;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.Map;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import net.sf.hibernate.AssertionFailure;import net.sf.hibernate.Hibernate;import net.sf.hibernate.HibernateException;import net.sf.hibernate.JDBCException;import net.sf.hibernate.LockMode;import net.sf.hibernate.MappingException;import net.sf.hibernate.QueryException;import net.sf.hibernate.StaleObjectStateException;import net.sf.hibernate.id.IdentifierGeneratorFactory;import net.sf.hibernate.impl.MessageHelper;import net.sf.hibernate.sql.CaseFragment;import net.sf.hibernate.sql.Delete;import net.sf.hibernate.sql.Insert;import net.sf.hibernate.sql.JoinFragment;import net.sf.hibernate.sql.SimpleSelect;import net.sf.hibernate.sql.SelectFragment;import net.sf.hibernate.sql.Update;import net.sf.hibernate.type.AssociationType;import net.sf.hibernate.type.DiscriminatorType;import net.sf.hibernate.type.Type;import net.sf.hibernate.engine.SessionFactoryImplementor;import net.sf.hibernate.engine.SessionImplementor;import net.sf.hibernate.engine.Versioning;/** * A <tt>ClassPersister</tt> implementing the normalized "table-per-subclass" mapping strategy. *  * @author Gavin King */public class NormalizedEntityPersister extends AbstractEntityPersister {		private final SessionFactoryImplementor factory;		// the class hierarchy structure	private final String qualifiedTableName;	private final String[] tableNames;	private final String[] naturalOrderTableNames;	private final String[][] tableKeyColumns;	private final String[][] naturalOrderTableKeyColumns;		private final Class[] subclassClosure;	private final String[] subclassTableNameClosure;	private final String[][] subclassTableKeyColumns;	private final boolean[] isClassOrSuperclassTable;		// SQL strings	private final String[] sqlDeleteStrings;	private final String[] sqlInsertStrings;	private final String[] sqlIdentityInsertStrings;	private final String[] sqlUpdateStrings;		// properties of this class, including inherited properties	private final int[] propertyColumnSpans;	private final int[] propertyTables;	private final int[] naturalOrderPropertyTables;	private final boolean[] propertyHasColumns;	private final String[][] propertyColumnNames;	private final String[][] propertyColumnAliases;	private final String[] propertyFormulaTemplates;		// the closure of all properties in the entire hierarchy including	// subclasses and superclasses of this class	private final String[][] subclassPropertyColumnNameClosure;	private final int[] subclassPropertyTableNumberClosure;	private final Type[] subclassPropertyTypeClosure;	private final String[] subclassPropertyNameClosure;	private final int[] subclassPropertyEnableJoinedFetch;	private final boolean[] propertyDefinedOnSubclass;		private final HashMap tableNumberByPropertyPath = new HashMap();		// the closure of all columns used by the entire hierarchy including	// subclasses and superclasses of this class	private final int[] subclassColumnTableNumberClosure;	private final String[] subclassColumnClosure;	private final String[] subclassColumnClosureAliases;	private final int[] subclassFormulaTableNumberClosure;	private final String[] subclassFormulaTemplateClosure;	private final String[] subclassFormulaAliasClosure;		// subclass discrimination works by assigning particular	// values to certain combinations of null primary key	// values in the outer join using an SQL CASE	private final HashMap subclassesByDiscriminatorValue = new HashMap();	private final String[] discriminatorValues;	private final String[] notNullColumns;	private final int[] tableNumbers;		private final DiscriminatorType discriminatorType;	private final String discriminatorSQLString;	private final String discriminatorColumnName;		private final String sqlConcreteSelectString;	private final String sqlVersionSelectString;		private UniqueEntityLoader loader;	private final Map lockers = new HashMap();		private static final Log log = LogFactory.getLog(NormalizedEntityPersister.class);		public void postInstantiate() throws MappingException {				initPropertyPaths(factory);						loader = createEntityLoader(factory);				createUniqueKeyLoaders(factory);			}			public boolean isDefinedOnSubclass(int i) {		return propertyDefinedOnSubclass[i];	}		public String getDiscriminatorColumnName() {		return discriminatorColumnName;	}		public String getDiscriminatorAlias() {		return getDiscriminatorColumnName(); // is always "clazz_", so just use columnname	}		public Type getSubclassPropertyType(int i) {		return subclassPropertyTypeClosure[i];	}	public String getSubclassPropertyName(int i) {		return subclassPropertyNameClosure[i];	}	public int countSubclassProperties() {		return subclassPropertyTypeClosure.length;	}		public String getSubclassPropertyTableName(int i) {		return subclassTableNameClosure[ subclassPropertyTableNumberClosure[i] ];	}		public String[] getSubclassPropertyColumnNames(int i) {		return subclassPropertyColumnNameClosure[i];	}		public String[] getPropertyColumnNames(int i) {		return propertyColumnAliases[i];	}		public Type getDiscriminatorType() {		return discriminatorType;	}		public Object getDiscriminatorSQLValue() {		return discriminatorSQLString;	}			public Class getSubclassForDiscriminatorValue(Object value) {		return (Class) subclassesByDiscriminatorValue.get(value);	}		public int enableJoinedFetch(int i) {		return subclassPropertyEnableJoinedFetch[i];	}		public Serializable getIdentifierSpace() {		return qualifiedTableName;	}		public Serializable[] getPropertySpaces() {		return tableNames; // don't need subclass tables, because they can't appear in conditions	}		//Access cached SQL		/**	 * The queries that delete rows by id (and version)	 */	protected final String[] getSQLDeleteStrings() {		return sqlDeleteStrings;	}		/**	 * The queries that insert rows with a given id	 */	protected final String[] getSQLInsertStrings() {		return sqlInsertStrings;	}		/**	 * The queries that insert rows, letting the database generate an id	 */	protected final String[] getSQLIdentityInsertStrings() {		return sqlIdentityInsertStrings;	}		/**	 * The queries that update rows by id (and version)	 */	protected final String[] getSQLUpdateStrings() {		return sqlUpdateStrings;	}		protected final String getVersionSelectString() {		return sqlVersionSelectString;	}		// Generate all the SQL		/**	 * Generate the SQL that deletes rows by id (and version)	 */	protected String[] generateDeleteStrings() {		String[] result = new String[ naturalOrderTableNames.length ];		for ( int i=0; i<naturalOrderTableNames.length; i++ ) {			Delete delete = new Delete()				.setTableName( naturalOrderTableNames[i] )				.setPrimaryKeyColumnNames( naturalOrderTableKeyColumns[i] );			if (i==0) delete.setVersionColumnName( getVersionColumnName() );			result[i] = delete.toStatementString();		}		return result;	}		/**	 * Generate the SQL that inserts rows	 */	protected String[] generateInsertStrings(boolean identityInsert, boolean[] includeProperty) {				String[] result = new String[naturalOrderTableNames.length];		for ( int j=0; j<naturalOrderTableNames.length; j++ ) {						Insert insert = new Insert( getDialect() )				.setTableName( naturalOrderTableNames[j] );							for (int i=0; i<getPropertyTypes().length; i++) {				if ( includeProperty[i] && naturalOrderPropertyTables[i]==j ) {					insert.addColumns( propertyColumnNames[i] );				}			}						if (identityInsert && j==0) {				insert.addIdentityColumn( naturalOrderTableKeyColumns[j][0] );			}			else {				insert.addColumns( naturalOrderTableKeyColumns[j] );			}						result[j] = insert.toStatementString();					}		return result;	}		/**	 * Generate the SQL that updates rows by id (and version)	 */	protected String[] generateUpdateStrings(boolean[] includeProperty) {		String[] result = new String[ naturalOrderTableNames.length ];		for ( int j=0; j<naturalOrderTableNames.length; j++ ) {			Update update = new Update()				.setTableName( naturalOrderTableNames[j] )				.setPrimaryKeyColumnNames( naturalOrderTableKeyColumns[j] );							if (j==0) update.setVersionColumnName( getVersionColumnName() );						boolean hasColumns = false;			for (int i=0; i<propertyColumnNames.length; i++) {				if ( includeProperty[i] && naturalOrderPropertyTables[i]==j ) {					update.addColumns( propertyColumnNames[i] );					hasColumns = hasColumns || propertyColumnNames[i].length > 0;				}			}						result[j] = hasColumns ? update.toStatementString() : null;		}		return result;	}		/**	 * Generate the SQL that pessimistic locks a row by id (and version)	 */	protected String generateLockString() {		SimpleSelect select = new SimpleSelect()			.setTableName(qualifiedTableName)			.addColumn( super.getIdentifierColumnNames()[0] )			.addCondition( super.getIdentifierColumnNames(), "=?" );		if ( isVersioned() ) {			select.addWhereToken("and")				.addCondition( getVersionColumnName(), "=?" );		}		return select.toStatementString();	}	/**	 * Generate the SQL that selects a row by id, excluding subclasses	 */	protected String getConcreteSelectString() {		return sqlConcreteSelectString;	}		private static final String CONCRETE_ALIAS = "x";		protected String generateConcreteSelectString() {		String select = "select " + 			StringHelper.join( 				StringHelper.COMMA_SPACE, 				StringHelper.qualify( CONCRETE_ALIAS, getIdentifierColumnNames() ) 			) +			concretePropertySelectFragment( CONCRETE_ALIAS, getPropertyUpdateability() ) + 			" from " +			fromTableFragment(CONCRETE_ALIAS) + 			fromJoinFragment(CONCRETE_ALIAS, true, false) +			" where " +			whereJoinFragment(CONCRETE_ALIAS, true, false) +			StringHelper.join(				"=? and ", 				StringHelper.qualify( CONCRETE_ALIAS, getIdentifierColumnNames() ) 			) +			"=?";		if ( isVersioned() ) {			select += 				" and " + 				getVersionColumnName() + 				"=?";		} 		return select;	}		/**	 * Marshall the fields of a persistent instance to a prepared statement	 */	protected int dehydrate(Serializable id, Object[] fields, boolean[] includeProperty, PreparedStatement[] statements, SessionImplementor session) throws SQLException, HibernateException {				if ( log.isTraceEnabled() ) log.trace( "Dehydrating entity: " + MessageHelper.infoString(this, id) );				int versionParam = 0;				for ( int i=0; i<tableNames.length; i++ ) {			int index = dehydrate(id, fields, includeProperty, i, statements[i], session);			if (i==0) versionParam = index;		}				return versionParam;			}		private int dehydrate(Serializable id, Object[] fields, boolean[] includeProperty, int table, PreparedStatement statement, SessionImplementor session) throws SQLException, HibernateException {				if (statement==null) return -1;				int index = 1;				for (int j=0; j<getHydrateSpan(); j++) {						if ( includeProperty[j] && naturalOrderPropertyTables[j]==table ) {				getPropertyTypes()[j].nullSafeSet( statement, fields[j], index, session );				index += propertyColumnSpans[j];			}					}				if ( id!=null ) {			getIdentifierType().nullSafeSet( statement, id, index, session );			index+=getIdentifierColumnNames().length;		}				return index;	}			// Execute the SQL:		/**	 * Load an instance using either the <tt>forUpdateLoader</tt> or the outer joining <tt>loader</tt>,	 * depending upon the value of the <tt>lock</tt> parameter	 */	public Object load(Serializable id,	Object optionalObject, LockMode lockMode, SessionImplementor session)	throws HibernateException {				if ( log.isTraceEnabled() ) log.trace( "Materializing entity: " + MessageHelper.infoString(this, id) );				try {					Object result = loader.load(session, id, optionalObject);					if (result!=null) lock(id, getVersion(result), result, lockMode, session);					return result;

⌨️ 快捷键说明

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