📄 abstractentitypersister.java
字号:
//$Id: AbstractEntityPersister.java 9575 2006-03-08 05:17:04Z steve.ebersole@jboss.com $
package org.hibernate.persister.entity;
import java.io.Serializable;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.List;
import net.sf.cglib.transform.impl.InterceptFieldEnabled;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.StaleObjectStateException;
import org.hibernate.cache.CacheConcurrencyStrategy;
import org.hibernate.cache.CacheKey;
import org.hibernate.cache.entry.CacheEntry;
import org.hibernate.cache.entry.CacheEntryStructure;
import org.hibernate.cache.entry.StructuredCacheEntry;
import org.hibernate.cache.entry.UnstructuredCacheEntry;
import org.hibernate.engine.CascadeStyle;
import org.hibernate.engine.CascadingAction;
import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.Versioning;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.IdentifierGeneratorFactory;
import org.hibernate.id.PostInsertIdentifierGenerator;
import org.hibernate.id.PostInsertIdentityPersister;
import org.hibernate.intercept.FieldInterceptor;
import org.hibernate.intercept.LazyPropertyInitializer;
import org.hibernate.loader.entity.BatchingEntityLoader;
import org.hibernate.loader.entity.CascadeEntityLoader;
import org.hibernate.loader.entity.EntityLoader;
import org.hibernate.loader.entity.UniqueEntityLoader;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.property.BackrefPropertyAccessor;
import org.hibernate.sql.Alias;
import org.hibernate.sql.Delete;
import org.hibernate.sql.Insert;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.Select;
import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.Template;
import org.hibernate.sql.Update;
import org.hibernate.tuple.EntityMetamodel;
import org.hibernate.tuple.EntityTuplizer;
import org.hibernate.tuple.Tuplizer;
import org.hibernate.type.AbstractComponentType;
import org.hibernate.type.AssociationType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import org.hibernate.type.VersionType;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.FilterHelper;
import org.hibernate.util.GetGeneratedKeysHelper;
import org.hibernate.util.StringHelper;
/**
* Basic functionality for persisting an entity via JDBC
* through either generated or custom SQL
*
* @author Gavin King
*/
public abstract class AbstractEntityPersister
implements OuterJoinLoadable, Queryable, ClassMetadata, UniqueKeyLoadable,
SQLLoadable, LazyPropertyInitializer, PostInsertIdentityPersister {
private static final Log log = LogFactory.getLog( AbstractEntityPersister.class );
public static final String ENTITY_CLASS = "class";
// moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private final SessionFactoryImplementor factory;
private final CacheConcurrencyStrategy cache;
private final boolean isLazyPropertiesCacheable;
private final CacheEntryStructure cacheEntryStructure;
private final EntityMetamodel entityMetamodel;
private final Map entityNameBySubclass = new HashMap();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private final String[] rootTableKeyColumnNames;
private final String[] identifierAliases;
private final int identifierColumnSpan;
private final String versionColumnName;
private final boolean hasFormulaProperties;
private final int batchSize;
private final boolean hasSubselectLoadableCollections;
protected final String rowIdName;
private final Set lazyProperties;
// The optional SQL string defined in the where attribute
private final String sqlWhereString;
private final String sqlWhereStringTemplate;
//information about properties of this class,
//including inherited properties
//(only really needed for updatable/insertable properties)
private final int[] propertyColumnSpans;
private final String[] propertySubclassNames;
private final String[][] propertyColumnAliases;
private final String[][] propertyColumnNames;
private final String[][] propertyColumnFormulaTemplates;
private final boolean[][] propertyColumnUpdateable;
private final boolean[][] propertyColumnInsertable;
private final boolean[] propertyUniqueness;
private final boolean[] propertySelectable;
//information about lazy properties of this class
private final String[] lazyPropertyNames;
private final int[] lazyPropertyNumbers;
private final Type[] lazyPropertyTypes;
private final String[][] lazyPropertyColumnAliases;
//information about all properties in class hierarchy
private final String[] subclassPropertyNameClosure;
private final String[] subclassPropertySubclassNameClosure;
private final Type[] subclassPropertyTypeClosure;
private final String[][] subclassPropertyFormulaTemplateClosure;
private final String[][] subclassPropertyColumnNameClosure;
private final FetchMode[] subclassPropertyFetchModeClosure;
private final boolean[] subclassPropertyNullabilityClosure;
private final boolean[] propertyDefinedOnSubclass;
private final int[][] subclassPropertyColumnNumberClosure;
private final int[][] subclassPropertyFormulaNumberClosure;
private final CascadeStyle[] subclassPropertyCascadeStyleClosure;
//information about all columns/formulas in class hierarchy
private final String[] subclassColumnClosure;
private final boolean[] subclassColumnLazyClosure;
private final String[] subclassColumnAliasClosure;
private final boolean[] subclassColumnSelectableClosure;
private final String[] subclassFormulaClosure;
private final String[] subclassFormulaTemplateClosure;
private final String[] subclassFormulaAliasClosure;
private final boolean[] subclassFormulaLazyClosure;
// dynamic filters attached to the class-level
private final FilterHelper filterHelper;
private final Map uniqueKeyLoaders = new HashMap();
private final Map lockers = new HashMap();
private final Map loaders = new HashMap();
// SQL strings
private String sqlVersionSelectString;
private String sqlSnapshotSelectString;
private String sqlLazySelectString;
private String sqlIdentityInsertString;
private String sqlUpdateByRowIdString;
private String sqlLazyUpdateByRowIdString;
private String[] sqlDeleteStrings;
private String[] sqlInsertStrings;
private String[] sqlUpdateStrings;
private String[] sqlLazyUpdateStrings;
private String sqlInsertGeneratedValuesSelectString;
private String sqlUpdateGeneratedValuesSelectString;
//Custom SQL (would be better if these were private)
protected boolean[] insertCallable;
protected boolean[] updateCallable;
protected boolean[] deleteCallable;
protected String[] customSQLInsert;
protected String[] customSQLUpdate;
protected String[] customSQLDelete;
private boolean[] tableHasColumns;
private final String loaderName;
private UniqueEntityLoader queryLoader;
private final String temporaryIdTableName;
private final String temporaryIdTableDDL;
private final Map subclassPropertyAliases = new HashMap();
private final Map subclassPropertyColumnNames = new HashMap();
protected final BasicEntityPropertyMapping propertyMapping;
protected void addDiscriminatorToInsert(Insert insert) {}
protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {}
protected abstract int[] getSubclassColumnTableNumberClosure();
protected abstract int[] getSubclassFormulaTableNumberClosure();
public abstract String getSubclassTableName(int j);
protected abstract String[] getSubclassTableKeyColumns(int j);
protected abstract boolean isClassOrSuperclassTable(int j);
protected abstract int getSubclassTableSpan();
protected abstract int getTableSpan();
protected abstract boolean isTableCascadeDeleteEnabled(int j);
protected abstract String getTableName(int j);
protected abstract String[] getKeyColumns(int j);
protected abstract boolean isPropertyOfTable(int property, int j);
protected abstract int[] getPropertyTableNumbersInSelect();
protected abstract int[] getPropertyTableNumbers();
protected abstract int getSubclassPropertyTableNumber(int i);
protected abstract String filterFragment(String alias) throws MappingException;
private static final String DISCRIMINATOR_ALIAS = "clazz_";
public String getDiscriminatorColumnName() {
return DISCRIMINATOR_ALIAS;
}
protected String getDiscriminatorAlias() {
return DISCRIMINATOR_ALIAS;
}
protected String getDiscriminatorFormulaTemplate() {
return null;
}
protected boolean isInverseTable(int j) {
return false;
}
protected boolean isNullableTable(int j) {
return false;
}
protected boolean isNullableSubclassTable(int j) {
return false;
}
protected boolean isInverseSubclassTable(int j) {
return false;
}
public boolean isSubclassEntityName(String entityName) {
return entityMetamodel.getSubclassEntityNames().contains(entityName);
}
private boolean[] getTableHasColumns() {
return tableHasColumns;
}
public String[] getRootTableKeyColumnNames() {
return rootTableKeyColumnNames;
}
protected String[] getSQLUpdateByRowIdStrings() {
if ( sqlUpdateByRowIdString == null ) {
throw new AssertionFailure( "no update by row id" );
}
String[] result = new String[getTableSpan()];
result[0] = sqlUpdateByRowIdString;
for ( int i = 1; i < getTableSpan(); i++ ) result[i] = sqlUpdateStrings[i];
return result;
}
protected String[] getSQLLazyUpdateByRowIdStrings() {
if ( sqlLazyUpdateByRowIdString == null ) {
throw new AssertionFailure( "no update by row id" );
}
String[] result = new String[getTableSpan()];
result[0] = sqlLazyUpdateByRowIdString;
for ( int i = 1; i < getTableSpan(); i++ ) result[i] = sqlLazyUpdateStrings[i];
return result;
}
protected String getSQLSnapshotSelectString() {
return sqlSnapshotSelectString;
}
protected String getSQLLazySelectString() {
return sqlLazySelectString;
}
protected String[] getSQLDeleteStrings() {
return sqlDeleteStrings;
}
protected String[] getSQLInsertStrings() {
return sqlInsertStrings;
}
protected String[] getSQLUpdateStrings() {
return sqlUpdateStrings;
}
protected String[] getSQLLazyUpdateStrings() {
return sqlLazyUpdateStrings;
}
/**
* The query that inserts a row, letting the database generate an id
*/
protected String getSQLIdentityInsertString() {
return sqlIdentityInsertString;
}
protected String getVersionSelectString() {
return sqlVersionSelectString;
}
protected boolean isInsertCallable(int j) {
return insertCallable[j];
}
protected boolean isUpdateCallable(int j) {
return updateCallable[j];
}
protected boolean isDeleteCallable(int j) {
return deleteCallable[j];
}
protected boolean isSubclassPropertyDeferred(String propertyName, String entityName) {
return false;
}
protected boolean isSubclassTableSequentialSelect(int j) {
return false;
}
public boolean hasSequentialSelect() {
return false;
}
/**
* Decide which tables need to be updated
*/
protected boolean[] getTableUpdateNeeded(final int[] dirtyProperties, boolean hasDirtyCollection) {
if ( dirtyProperties == null ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -