📄 entitypersister.java
字号:
//$Id: EntityPersister.java,v 1.38.2.34 2003/11/29 07:55:15 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.SimpleEntityLoader;import net.sf.hibernate.loader.UniqueEntityLoader;import net.sf.hibernate.mapping.Column;import net.sf.hibernate.mapping.Value;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.HibernateException;import net.sf.hibernate.JDBCException;import net.sf.hibernate.LockMode;import net.sf.hibernate.MappingException;import net.sf.hibernate.StaleObjectStateException;import net.sf.hibernate.id.IdentifierGeneratorFactory;import net.sf.hibernate.impl.MessageHelper;import net.sf.hibernate.sql.Delete;import net.sf.hibernate.sql.InFragment;import net.sf.hibernate.sql.Insert;import net.sf.hibernate.sql.SimpleSelect;import net.sf.hibernate.sql.SelectFragment;import net.sf.hibernate.sql.Update;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;/** * The default implementation of the <tt>ClassPersister</tt> interface. * Implements the "table-per-class-hierarchy" mapping strategy for an entity * class. * * @author Gavin King */public class EntityPersister extends AbstractEntityPersister implements Queryable { private final SessionFactoryImplementor factory; // the class hierarchy structure private final String qualifiedTableName; private final String[] tableNames; private final boolean hasUpdateableColumns; private final Class[] subclassClosure; // SQL strings private final String sqlDeleteString; private final String sqlInsertString; private final String sqlUpdateString; private final String sqlIdentityInsertString; private final String sqlConcreteSelectString; private final String sqlVersionSelectString; // properties of this class, including inherited properties private final int[] propertyColumnSpans; private final boolean[] propertyDefinedOnSubclass; private final String[][] propertyColumnNames; private final String[][] propertyColumnAliases; private final String[] propertyFormulaTemplates; // the closure of all columns used by the entire hierarchy including // subclasses and superclasses of this class private final String[] subclassColumnClosure; private final String[] subclassColumnAliasClosure; private final String[] subclassFormulaTemplateClosure; private final String[] subclassFormulaClosure; private final String[] subclassFormulaAliasClosure; // the closure of all properties in the entire hierarchy including // subclasses and superclasses of this class private final String[][] subclassPropertyColumnNameClosure; private final String[] subclassPropertyNameClosure; private final Type[] subclassPropertyTypeClosure; private final int[] subclassPropertyEnableJoinedFetch; // discriminator column private final HashMap subclassesByDiscriminatorValue = new HashMap(); private final boolean forceDiscriminator; private final String discriminatorColumnName; private final String discriminatorAlias; private final Type discriminatorType; private final Object discriminatorSQLValue; private final Map loaders = new HashMap(); private final Map lockers = new HashMap(); private static final Object NULL_DISCRIMINATOR = new Object(); private static final Object NOT_NULL_DISCRIMINATOR = new Object(); private static final Log log = LogFactory.getLog(EntityPersister.class); public void postInstantiate() throws MappingException { initPropertyPaths(factory); UniqueEntityLoader loader = createEntityLoader(factory); loaders.put( LockMode.NONE, loader ); loaders.put( LockMode.READ, loader ); String selectForUpdate = factory.getDialect().supportsForUpdate() ? generateSelectForUpdateString() : generateSelectString(); loaders.put( LockMode.UPGRADE, new SimpleEntityLoader( this, selectForUpdate, LockMode.UPGRADE ) ); String selectForUpdateNowait = factory.getDialect().supportsForUpdateNowait() ? generateSelectForUpdateNowaitString() : selectForUpdate; loaders.put( LockMode.UPGRADE_NOWAIT, new SimpleEntityLoader( this, selectForUpdateNowait, LockMode.UPGRADE_NOWAIT ) ); createUniqueKeyLoaders(factory); } public boolean isDefinedOnSubclass(int i) { return propertyDefinedOnSubclass[i]; } public String getDiscriminatorColumnName() { return discriminatorColumnName; } public String getDiscriminatorAlias() { return discriminatorAlias; } public int enableJoinedFetch(int i) { return subclassPropertyEnableJoinedFetch[i]; } public Type getSubclassPropertyType(int i) { return subclassPropertyTypeClosure[i]; } public String getSubclassPropertyName(int i) { return subclassPropertyNameClosure[i]; } public int countSubclassProperties() { return subclassPropertyTypeClosure.length; } public String getTableName() { return qualifiedTableName; } 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 discriminatorSQLValue; } public Class[] getSubclassClosure() { return subclassClosure; } public Class getSubclassForDiscriminatorValue(Object value) { if (value==null) { return (Class) subclassesByDiscriminatorValue.get(NULL_DISCRIMINATOR); } else { Class result = (Class) subclassesByDiscriminatorValue.get(value); if (result==null) result = (Class) subclassesByDiscriminatorValue.get(NOT_NULL_DISCRIMINATOR); return result; } } public Serializable getIdentifierSpace() { return qualifiedTableName; } public Serializable[] getPropertySpaces() { return tableNames; } //Access cached SQL /** * The query that deletes a row by id (and version) */ protected final String getSQLDeleteString() { return sqlDeleteString; } /** * The query that inserts a row with a given id */ protected final String getSQLInsertString() { return sqlInsertString; } /** * The query that inserts a row, letting the database generate an id */ protected final String getSQLIdentityInsertString() { return sqlIdentityInsertString; } /** * The query that updates a row by id (and version) */ protected final String getSQLUpdateString() { return sqlUpdateString; } protected final String getVersionSelectString() { return sqlVersionSelectString; } // Generate all the SQL /** * Generate the SQL that deletes a row by id (and version) */ protected String generateDeleteString() { return new Delete() .setTableName( getTableName() ) .setPrimaryKeyColumnNames( getIdentifierColumnNames() ) .setVersionColumnName( getVersionColumnName() ) .toStatementString(); } /** * Generate the SQL that inserts a row */ protected String generateInsertString(boolean identityInsert, boolean[] includeProperty) { Insert insert = new Insert( getDialect() ) .setTableName( getTableName() ); for (int i=0; i<getHydrateSpan(); i++) { if ( includeProperty[i] ) insert.addColumns( propertyColumnNames[i] ); } final boolean includeDiscriminator = isPolymorphic() && InFragment.NULL!=discriminatorSQLValue && InFragment.NOT_NULL!=discriminatorSQLValue; if (includeDiscriminator) insert.addColumn( getDiscriminatorColumnName(), discriminatorSQLValue.toString() ); if (!identityInsert) { insert.addColumns( getIdentifierColumnNames() ); } else { insert.addIdentityColumn( getIdentifierColumnNames()[0] ); } return insert.toStatementString(); } /** * Generate the SQL that selects a row by id using <tt>FOR UPDATE</tt> */ protected String generateSelectForUpdateString() { return generateSelectString() + " for update"; } /** * Generate the SQL that selects a row by id using <tt>FOR UPDATE</tt> */ protected String generateSelectForUpdateNowaitString() { return generateSelectString() + " for update nowait"; } /** * Generate the SQL that selects a row by id */ protected String generateSelectString() { SimpleSelect select = new SimpleSelect() .setTableName( getTableName() ) .addColumns( getIdentifierColumnNames() ) .addColumns(subclassColumnClosure, subclassColumnAliasClosure) .addColumns(subclassFormulaClosure, subclassFormulaAliasClosure); if ( hasSubclasses() ) select.addColumn( getDiscriminatorColumnName() , getDiscriminatorAlias() ); return select.addCondition( getIdentifierColumnNames(), "=?" ).toStatementString(); } /** * Generate the SQL that selects a row by id, excluding subclasses */ protected String generateConcreteSelectString(boolean[] includeProperty) { SimpleSelect select = new SimpleSelect() .setTableName( getTableName() ) .addColumns( getIdentifierColumnNames() ); for ( int i=0; i<getPropertyNames().length; i++ ) { if ( includeProperty[i] ) { //ie. not a formula, updateable select.addColumns( propertyColumnNames[i], propertyColumnAliases[i] ); } //don't handle formulas, cos they are not updateable } select.addCondition( getIdentifierColumnNames(), "=?" ); if ( isVersioned() ) { select.addWhereToken("and") .addCondition( getVersionColumnName(), "=?" ); } return select.toStatementString(); } /** * Generate the SQL that updates a row by id (and version) */ protected String generateUpdateString(boolean[] includeProperty) { return generateUpdate(includeProperty).toStatementString(); } protected String generateUpdateString(boolean[] includeProperty, Object[] oldFields) { Update update = generateUpdate(includeProperty); if ( optimisticLockMode()>Versioning.OPTIMISTIC_LOCK_VERSION && oldFields!=null ) { boolean[] includeInWhere = optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_ALL ? getPropertyUpdateability() : includeProperty; for ( int i=0; i<getHydrateSpan(); i++ ) { if ( includeInWhere[i] ) { if ( oldFields[i]==null) { update.addWhereColumns( propertyColumnNames[i], " is null"); } else { update.addWhereColumns( propertyColumnNames[i] ); } } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -