Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.hibernate.persister.entity.SingleTableEntityPersister Maven / Gradle / Ivy
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.persister.entity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.DynamicFilterAliasGenerator;
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.util.MarkerObject;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Formula;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.CustomSQL;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.SimpleValueBinding;
import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.relational.DerivedValue;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.sql.InFragment;
import org.hibernate.sql.Insert;
import org.hibernate.sql.SelectFragment;
import org.hibernate.type.AssociationType;
import org.hibernate.type.DiscriminatorType;
import org.hibernate.type.Type;
/**
* The default implementation of the EntityPersister interface.
* Implements the "table-per-class-hierarchy" or "roll-up" mapping strategy
* for an entity class and its inheritence hierarchy. This is implemented
* as a single table holding all classes in the hierarchy with a discrimator
* column used to determine which concrete class is referenced.
*
* @author Gavin King
*/
public class SingleTableEntityPersister extends AbstractEntityPersister {
// the class hierarchy structure
private final int joinSpan;
private final String[] qualifiedTableNames;
private final boolean[] isInverseTable;
private final boolean[] isNullableTable;
private final String[][] keyColumnNames;
private final boolean[] cascadeDeleteEnabled;
private final boolean hasSequentialSelects;
private final String[] spaces;
private final String[] subclassClosure;
private final String[] subclassTableNameClosure;
private final boolean[] subclassTableIsLazyClosure;
private final boolean[] isInverseSubclassTable;
private final boolean[] isNullableSubclassTable;
private final boolean[] subclassTableSequentialSelect;
private final String[][] subclassTableKeyColumnClosure;
private final boolean[] isClassOrSuperclassTable;
// properties of this class, including inherited properties
private final int[] propertyTableNumbers;
// the closure of all columns used by the entire hierarchy including
// subclasses and superclasses of this class
private final int[] subclassPropertyTableNumberClosure;
private final int[] subclassColumnTableNumberClosure;
private final int[] subclassFormulaTableNumberClosure;
// discriminator column
private final Map subclassesByDiscriminatorValue = new HashMap();
private final boolean forceDiscriminator;
private final String discriminatorColumnName;
private final String discriminatorColumnReaders;
private final String discriminatorColumnReaderTemplate;
private final String discriminatorFormula;
private final String discriminatorFormulaTemplate;
private final String discriminatorAlias;
private final Type discriminatorType;
private final Object discriminatorValue;
private final String discriminatorSQLValue;
private final boolean discriminatorInsertable;
private final String[] constraintOrderedTableNames;
private final String[][] constraintOrderedKeyColumnNames;
//private final Map propertyTableNumbersByName = new HashMap();
private final Map propertyTableNumbersByNameAndSubclass = new HashMap();
private final Map sequentialSelectStringsByEntityName = new HashMap();
private static final Object NULL_DISCRIMINATOR = new MarkerObject("");
private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject("");
private static final String NULL_STRING = "null";
private static final String NOT_NULL_STRING = "not null";
//INITIALIZATION:
public SingleTableEntityPersister(
final PersistentClass persistentClass,
final EntityRegionAccessStrategy cacheAccessStrategy,
final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy,
final SessionFactoryImplementor factory,
final Mapping mapping) throws HibernateException {
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory );
// CLASS + TABLE
joinSpan = persistentClass.getJoinClosureSpan()+1;
qualifiedTableNames = new String[joinSpan];
isInverseTable = new boolean[joinSpan];
isNullableTable = new boolean[joinSpan];
keyColumnNames = new String[joinSpan][];
final Table table = persistentClass.getRootTable();
qualifiedTableNames[0] = table.getQualifiedName(
factory.getDialect(),
factory.getSettings().getDefaultCatalogName(),
factory.getSettings().getDefaultSchemaName()
);
isInverseTable[0] = false;
isNullableTable[0] = false;
keyColumnNames[0] = getIdentifierColumnNames();
cascadeDeleteEnabled = new boolean[joinSpan];
// Custom sql
customSQLInsert = new String[joinSpan];
customSQLUpdate = new String[joinSpan];
customSQLDelete = new String[joinSpan];
insertCallable = new boolean[joinSpan];
updateCallable = new boolean[joinSpan];
deleteCallable = new boolean[joinSpan];
insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
customSQLInsert[0] = persistentClass.getCustomSQLInsert();
insertCallable[0] = customSQLInsert[0] != null && persistentClass.isCustomInsertCallable();
insertResultCheckStyles[0] = persistentClass.getCustomSQLInsertCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[0], insertCallable[0] )
: persistentClass.getCustomSQLInsertCheckStyle();
customSQLUpdate[0] = persistentClass.getCustomSQLUpdate();
updateCallable[0] = customSQLUpdate[0] != null && persistentClass.isCustomUpdateCallable();
updateResultCheckStyles[0] = persistentClass.getCustomSQLUpdateCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[0], updateCallable[0] )
: persistentClass.getCustomSQLUpdateCheckStyle();
customSQLDelete[0] = persistentClass.getCustomSQLDelete();
deleteCallable[0] = customSQLDelete[0] != null && persistentClass.isCustomDeleteCallable();
deleteResultCheckStyles[0] = persistentClass.getCustomSQLDeleteCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[0], deleteCallable[0] )
: persistentClass.getCustomSQLDeleteCheckStyle();
// JOINS
Iterator joinIter = persistentClass.getJoinClosureIterator();
int j = 1;
while ( joinIter.hasNext() ) {
Join join = (Join) joinIter.next();
qualifiedTableNames[j] = join.getTable().getQualifiedName(
factory.getDialect(),
factory.getSettings().getDefaultCatalogName(),
factory.getSettings().getDefaultSchemaName()
);
isInverseTable[j] = join.isInverse();
isNullableTable[j] = join.isOptional();
cascadeDeleteEnabled[j] = join.getKey().isCascadeDeleteEnabled() &&
factory.getDialect().supportsCascadeDelete();
customSQLInsert[j] = join.getCustomSQLInsert();
insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable();
insertResultCheckStyles[j] = join.getCustomSQLInsertCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[j], insertCallable[j] )
: join.getCustomSQLInsertCheckStyle();
customSQLUpdate[j] = join.getCustomSQLUpdate();
updateCallable[j] = customSQLUpdate[j] != null && join.isCustomUpdateCallable();
updateResultCheckStyles[j] = join.getCustomSQLUpdateCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[j], updateCallable[j] )
: join.getCustomSQLUpdateCheckStyle();
customSQLDelete[j] = join.getCustomSQLDelete();
deleteCallable[j] = customSQLDelete[j] != null && join.isCustomDeleteCallable();
deleteResultCheckStyles[j] = join.getCustomSQLDeleteCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[j], deleteCallable[j] )
: join.getCustomSQLDeleteCheckStyle();
Iterator iter = join.getKey().getColumnIterator();
keyColumnNames[j] = new String[ join.getKey().getColumnSpan() ];
int i = 0;
while ( iter.hasNext() ) {
Column col = (Column) iter.next();
keyColumnNames[j][i++] = col.getQuotedName( factory.getDialect() );
}
j++;
}
constraintOrderedTableNames = new String[qualifiedTableNames.length];
constraintOrderedKeyColumnNames = new String[qualifiedTableNames.length][];
for ( int i = qualifiedTableNames.length - 1, position = 0; i >= 0; i--, position++ ) {
constraintOrderedTableNames[position] = qualifiedTableNames[i];
constraintOrderedKeyColumnNames[position] = keyColumnNames[i];
}
spaces = ArrayHelper.join(
qualifiedTableNames,
ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() )
);
final boolean lazyAvailable = isInstrumented();
boolean hasDeferred = false;
ArrayList subclassTables = new ArrayList();
ArrayList joinKeyColumns = new ArrayList();
ArrayList isConcretes = new ArrayList();
ArrayList isDeferreds = new ArrayList();
ArrayList isInverses = new ArrayList();
ArrayList isNullables = new ArrayList();
ArrayList isLazies = new ArrayList();
subclassTables.add( qualifiedTableNames[0] );
joinKeyColumns.add( getIdentifierColumnNames() );
isConcretes.add(Boolean.TRUE);
isDeferreds.add(Boolean.FALSE);
isInverses.add(Boolean.FALSE);
isNullables.add(Boolean.FALSE);
isLazies.add(Boolean.FALSE);
joinIter = persistentClass.getSubclassJoinClosureIterator();
while ( joinIter.hasNext() ) {
Join join = (Join) joinIter.next();
isConcretes.add( persistentClass.isClassOrSuperclassJoin(join) );
isDeferreds.add( join.isSequentialSelect() );
isInverses.add( join.isInverse() );
isNullables.add( join.isOptional() );
isLazies.add( lazyAvailable && join.isLazy() );
if ( join.isSequentialSelect() && !persistentClass.isClassOrSuperclassJoin(join) ) hasDeferred = true;
subclassTables.add( join.getTable().getQualifiedName(
factory.getDialect(),
factory.getSettings().getDefaultCatalogName(),
factory.getSettings().getDefaultSchemaName()
) );
Iterator iter = join.getKey().getColumnIterator();
String[] keyCols = new String[ join.getKey().getColumnSpan() ];
int i = 0;
while ( iter.hasNext() ) {
Column col = (Column) iter.next();
keyCols[i++] = col.getQuotedName( factory.getDialect() );
}
joinKeyColumns.add(keyCols);
}
subclassTableSequentialSelect = ArrayHelper.toBooleanArray(isDeferreds);
subclassTableNameClosure = ArrayHelper.toStringArray(subclassTables);
subclassTableIsLazyClosure = ArrayHelper.toBooleanArray(isLazies);
subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray( joinKeyColumns );
isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes);
isInverseSubclassTable = ArrayHelper.toBooleanArray(isInverses);
isNullableSubclassTable = ArrayHelper.toBooleanArray(isNullables);
hasSequentialSelects = hasDeferred;
// DISCRIMINATOR
if ( persistentClass.isPolymorphic() ) {
Value discrimValue = persistentClass.getDiscriminator();
if (discrimValue==null) {
throw new MappingException("discriminator mapping required for single table polymorphic persistence");
}
forceDiscriminator = persistentClass.isForceDiscriminator();
Selectable selectable = (Selectable) discrimValue.getColumnIterator().next();
if ( discrimValue.hasFormula() ) {
Formula formula = (Formula) selectable;
discriminatorFormula = formula.getFormula();
discriminatorFormulaTemplate = formula.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
discriminatorColumnName = null;
discriminatorColumnReaders = null;
discriminatorColumnReaderTemplate = null;
discriminatorAlias = "clazz_";
}
else {
Column column = (Column) selectable;
discriminatorColumnName = column.getQuotedName( factory.getDialect() );
discriminatorColumnReaders = column.getReadExpr( factory.getDialect() );
discriminatorColumnReaderTemplate = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
discriminatorAlias = column.getAlias( factory.getDialect(), persistentClass.getRootTable() );
discriminatorFormula = null;
discriminatorFormulaTemplate = null;
}
discriminatorType = persistentClass.getDiscriminator().getType();
if ( persistentClass.isDiscriminatorValueNull() ) {
discriminatorValue = NULL_DISCRIMINATOR;
discriminatorSQLValue = InFragment.NULL;
discriminatorInsertable = false;
}
else if ( persistentClass.isDiscriminatorValueNotNull() ) {
discriminatorValue = NOT_NULL_DISCRIMINATOR;
discriminatorSQLValue = InFragment.NOT_NULL;
discriminatorInsertable = false;
}
else {
discriminatorInsertable = persistentClass.isDiscriminatorInsertable() && !discrimValue.hasFormula();
try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
discriminatorValue = dtype.stringToObject( persistentClass.getDiscriminatorValue() );
discriminatorSQLValue = dtype.objectToSQLString( discriminatorValue, factory.getDialect() );
}
catch (ClassCastException cce) {
throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
}
catch (Exception e) {
throw new MappingException("Could not format discriminator value to SQL string", e);
}
}
}
else {
forceDiscriminator = false;
discriminatorInsertable = false;
discriminatorColumnName = null;
discriminatorColumnReaders = null;
discriminatorColumnReaderTemplate = null;
discriminatorAlias = null;
discriminatorType = null;
discriminatorValue = null;
discriminatorSQLValue = null;
discriminatorFormula = null;
discriminatorFormulaTemplate = null;
}
// PROPERTIES
propertyTableNumbers = new int[ getPropertySpan() ];
Iterator iter = persistentClass.getPropertyClosureIterator();
int i=0;
while( iter.hasNext() ) {
Property prop = (Property) iter.next();
propertyTableNumbers[i++] = persistentClass.getJoinNumber(prop);
}
//TODO: code duplication with JoinedSubclassEntityPersister
ArrayList columnJoinNumbers = new ArrayList();
ArrayList formulaJoinedNumbers = new ArrayList();
ArrayList propertyJoinNumbers = new ArrayList();
iter = persistentClass.getSubclassPropertyClosureIterator();
while ( iter.hasNext() ) {
Property prop = (Property) iter.next();
Integer join = persistentClass.getJoinNumber(prop);
propertyJoinNumbers.add(join);
//propertyTableNumbersByName.put( prop.getName(), join );
propertyTableNumbersByNameAndSubclass.put(
prop.getPersistentClass().getEntityName() + '.' + prop.getName(),
join
);
Iterator citer = prop.getColumnIterator();
while ( citer.hasNext() ) {
Selectable thing = (Selectable) citer.next();
if ( thing.isFormula() ) {
formulaJoinedNumbers.add(join);
}
else {
columnJoinNumbers.add(join);
}
}
}
subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnJoinNumbers);
subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaJoinedNumbers);
subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propertyJoinNumbers);
int subclassSpan = persistentClass.getSubclassSpan() + 1;
subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName();
if ( persistentClass.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
}
// SUBCLASSES
if ( persistentClass.isPolymorphic() ) {
iter = persistentClass.getSubclassIterator();
int k=1;
while ( iter.hasNext() ) {
Subclass sc = (Subclass) iter.next();
subclassClosure[k++] = sc.getEntityName();
if ( sc.isDiscriminatorValueNull() ) {
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() );
}
else if ( sc.isDiscriminatorValueNotNull() ) {
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
}
else {
try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
subclassesByDiscriminatorValue.put(
dtype.stringToObject( sc.getDiscriminatorValue() ),
sc.getEntityName()
);
}
catch (ClassCastException cce) {
throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
}
catch (Exception e) {
throw new MappingException("Error parsing discriminator value", e);
}
}
}
}
initLockers();
initSubclassPropertyAliasesMap(persistentClass);
postConstruct(mapping);
}
public SingleTableEntityPersister(
final EntityBinding entityBinding,
final EntityRegionAccessStrategy cacheAccessStrategy,
final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy,
final SessionFactoryImplementor factory,
final Mapping mapping) throws HibernateException {
super( entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory );
// CLASS + TABLE
// TODO: fix when joins are working (HHH-6391)
//joinSpan = entityBinding.getJoinClosureSpan() + 1;
joinSpan = 1;
qualifiedTableNames = new String[joinSpan];
isInverseTable = new boolean[joinSpan];
isNullableTable = new boolean[joinSpan];
keyColumnNames = new String[joinSpan][];
final TableSpecification table = entityBinding.getPrimaryTable();
qualifiedTableNames[0] = table.getQualifiedName( factory.getDialect() );
isInverseTable[0] = false;
isNullableTable[0] = false;
keyColumnNames[0] = getIdentifierColumnNames();
cascadeDeleteEnabled = new boolean[joinSpan];
// Custom sql
customSQLInsert = new String[joinSpan];
customSQLUpdate = new String[joinSpan];
customSQLDelete = new String[joinSpan];
insertCallable = new boolean[joinSpan];
updateCallable = new boolean[joinSpan];
deleteCallable = new boolean[joinSpan];
insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
initializeCustomSql( entityBinding.getCustomInsert(), 0, customSQLInsert, insertCallable, insertResultCheckStyles );
initializeCustomSql( entityBinding.getCustomUpdate(), 0, customSQLUpdate, updateCallable, updateResultCheckStyles );
initializeCustomSql( entityBinding.getCustomDelete(), 0, customSQLDelete, deleteCallable, deleteResultCheckStyles );
// JOINS
// TODO: add join stuff when HHH-6391 is working
constraintOrderedTableNames = new String[qualifiedTableNames.length];
constraintOrderedKeyColumnNames = new String[qualifiedTableNames.length][];
for ( int i = qualifiedTableNames.length - 1, position = 0; i >= 0; i--, position++ ) {
constraintOrderedTableNames[position] = qualifiedTableNames[i];
constraintOrderedKeyColumnNames[position] = keyColumnNames[i];
}
spaces = ArrayHelper.join(
qualifiedTableNames,
ArrayHelper.toStringArray( entityBinding.getSynchronizedTableNames() )
);
final boolean lazyAvailable = isInstrumented();
boolean hasDeferred = false;
ArrayList subclassTables = new ArrayList();
ArrayList joinKeyColumns = new ArrayList();
ArrayList isConcretes = new ArrayList();
ArrayList isDeferreds = new ArrayList();
ArrayList isInverses = new ArrayList();
ArrayList isNullables = new ArrayList();
ArrayList isLazies = new ArrayList();
subclassTables.add( qualifiedTableNames[0] );
joinKeyColumns.add( getIdentifierColumnNames() );
isConcretes.add(Boolean.TRUE);
isDeferreds.add(Boolean.FALSE);
isInverses.add(Boolean.FALSE);
isNullables.add(Boolean.FALSE);
isLazies.add(Boolean.FALSE);
// TODO: add join stuff when HHH-6391 is working
subclassTableSequentialSelect = ArrayHelper.toBooleanArray(isDeferreds);
subclassTableNameClosure = ArrayHelper.toStringArray(subclassTables);
subclassTableIsLazyClosure = ArrayHelper.toBooleanArray(isLazies);
subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray( joinKeyColumns );
isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes);
isInverseSubclassTable = ArrayHelper.toBooleanArray(isInverses);
isNullableSubclassTable = ArrayHelper.toBooleanArray(isNullables);
hasSequentialSelects = hasDeferred;
// DISCRIMINATOR
if ( entityBinding.isPolymorphic() ) {
SimpleValue discriminatorRelationalValue = entityBinding.getHierarchyDetails().getEntityDiscriminator().getBoundValue();
if ( discriminatorRelationalValue == null ) {
throw new MappingException("discriminator mapping required for single table polymorphic persistence");
}
forceDiscriminator = entityBinding.getHierarchyDetails().getEntityDiscriminator().isForced();
if ( DerivedValue.class.isInstance( discriminatorRelationalValue ) ) {
DerivedValue formula = ( DerivedValue ) discriminatorRelationalValue;
discriminatorFormula = formula.getExpression();
discriminatorFormulaTemplate = getTemplateFromString( formula.getExpression(), factory );
discriminatorColumnName = null;
discriminatorColumnReaders = null;
discriminatorColumnReaderTemplate = null;
discriminatorAlias = "clazz_";
}
else {
org.hibernate.metamodel.relational.Column column = ( org.hibernate.metamodel.relational.Column ) discriminatorRelationalValue;
discriminatorColumnName = column.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() );
discriminatorColumnReaders =
column.getReadFragment() == null ?
column.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ) :
column.getReadFragment();
discriminatorColumnReaderTemplate = getTemplateFromColumn( column, factory );
discriminatorAlias = column.getAlias( factory.getDialect() );
discriminatorFormula = null;
discriminatorFormulaTemplate = null;
}
discriminatorType = entityBinding.getHierarchyDetails()
.getEntityDiscriminator()
.getExplicitHibernateTypeDescriptor()
.getResolvedTypeMapping();
if ( entityBinding.getDiscriminatorMatchValue() == null ) {
discriminatorValue = NULL_DISCRIMINATOR;
discriminatorSQLValue = InFragment.NULL;
discriminatorInsertable = false;
}
else if ( entityBinding.getDiscriminatorMatchValue().equals( NULL_STRING ) ) {
discriminatorValue = NOT_NULL_DISCRIMINATOR;
discriminatorSQLValue = InFragment.NOT_NULL;
discriminatorInsertable = false;
}
else if ( entityBinding.getDiscriminatorMatchValue().equals( NOT_NULL_STRING ) ) {
discriminatorValue = NOT_NULL_DISCRIMINATOR;
discriminatorSQLValue = InFragment.NOT_NULL;
discriminatorInsertable = false;
}
else {
discriminatorInsertable = entityBinding.getHierarchyDetails().getEntityDiscriminator().isInserted()
&& ! DerivedValue.class.isInstance( discriminatorRelationalValue );
try {
DiscriminatorType dtype = ( DiscriminatorType ) discriminatorType;
discriminatorValue = dtype.stringToObject( entityBinding.getDiscriminatorMatchValue() );
discriminatorSQLValue = dtype.objectToSQLString( discriminatorValue, factory.getDialect() );
}
catch (ClassCastException cce) {
throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
}
catch (Exception e) {
throw new MappingException("Could not format discriminator value to SQL string", e);
}
}
}
else {
forceDiscriminator = false;
discriminatorInsertable = false;
discriminatorColumnName = null;
discriminatorColumnReaders = null;
discriminatorColumnReaderTemplate = null;
discriminatorAlias = null;
discriminatorType = null;
discriminatorValue = null;
discriminatorSQLValue = null;
discriminatorFormula = null;
discriminatorFormulaTemplate = null;
}
// PROPERTIES
propertyTableNumbers = new int[ getPropertySpan() ];
int i=0;
for( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) {
// TODO: fix when joins are working (HHH-6391)
//propertyTableNumbers[i++] = entityBinding.getJoinNumber( attributeBinding);
if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) {
continue; // skip identifier binding
}
if ( ! attributeBinding.getAttribute().isSingular() ) {
continue;
}
propertyTableNumbers[ i++ ] = 0;
}
//TODO: code duplication with JoinedSubclassEntityPersister
ArrayList columnJoinNumbers = new ArrayList();
ArrayList formulaJoinedNumbers = new ArrayList();
ArrayList propertyJoinNumbers = new ArrayList();
for ( AttributeBinding attributeBinding : entityBinding.getSubEntityAttributeBindingClosure() ) {
if ( ! attributeBinding.getAttribute().isSingular() ) {
continue;
}
SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding;
// TODO: fix when joins are working (HHH-6391)
//int join = entityBinding.getJoinNumber(singularAttributeBinding);
int join = 0;
propertyJoinNumbers.add(join);
//propertyTableNumbersByName.put( singularAttributeBinding.getName(), join );
propertyTableNumbersByNameAndSubclass.put(
singularAttributeBinding.getContainer().getPathBase() + '.' + singularAttributeBinding.getAttribute().getName(),
join
);
for ( SimpleValueBinding simpleValueBinding : singularAttributeBinding.getSimpleValueBindings() ) {
if ( DerivedValue.class.isInstance( simpleValueBinding.getSimpleValue() ) ) {
formulaJoinedNumbers.add( join );
}
else {
columnJoinNumbers.add( join );
}
}
}
subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnJoinNumbers);
subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaJoinedNumbers);
subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propertyJoinNumbers);
int subclassSpan = entityBinding.getSubEntityBindingClosureSpan() + 1;
subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName();
if ( entityBinding.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
}
// SUBCLASSES
if ( entityBinding.isPolymorphic() ) {
int k=1;
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
subclassClosure[k++] = subEntityBinding.getEntity().getName();
if ( subEntityBinding.isDiscriminatorMatchValueNull() ) {
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
}
else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) {
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
}
else {
try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
subclassesByDiscriminatorValue.put(
dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ),
subEntityBinding.getEntity().getName()
);
}
catch (ClassCastException cce) {
throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
}
catch (Exception e) {
throw new MappingException("Error parsing discriminator value", e);
}
}
}
}
initLockers();
initSubclassPropertyAliasesMap( entityBinding );
postConstruct( mapping );
}
private static void initializeCustomSql(
CustomSQL customSql,
int i,
String[] sqlStrings,
boolean[] callable,
ExecuteUpdateResultCheckStyle[] checkStyles) {
sqlStrings[i] = customSql != null ? customSql.getSql(): null;
callable[i] = sqlStrings[i] != null && customSql.isCallable();
checkStyles[i] = customSql != null && customSql.getCheckStyle() != null ?
customSql.getCheckStyle() :
ExecuteUpdateResultCheckStyle.determineDefault( sqlStrings[i], callable[i] );
}
protected boolean isInverseTable(int j) {
return isInverseTable[j];
}
protected boolean isInverseSubclassTable(int j) {
return isInverseSubclassTable[j];
}
public String getDiscriminatorColumnName() {
return discriminatorColumnName;
}
public String getDiscriminatorColumnReaders() {
return discriminatorColumnReaders;
}
public String getDiscriminatorColumnReaderTemplate() {
return discriminatorColumnReaderTemplate;
}
protected String getDiscriminatorAlias() {
return discriminatorAlias;
}
protected String getDiscriminatorFormulaTemplate() {
return discriminatorFormulaTemplate;
}
public String getTableName() {
return qualifiedTableNames[0];
}
public Type getDiscriminatorType() {
return discriminatorType;
}
public Object getDiscriminatorValue() {
return discriminatorValue;
}
public String getDiscriminatorSQLValue() {
return discriminatorSQLValue;
}
public String[] getSubclassClosure() {
return subclassClosure;
}
public String getSubclassForDiscriminatorValue(Object value) {
if (value==null) {
return (String) subclassesByDiscriminatorValue.get(NULL_DISCRIMINATOR);
}
else {
String result = (String) subclassesByDiscriminatorValue.get(value);
if (result==null) result = (String) subclassesByDiscriminatorValue.get(NOT_NULL_DISCRIMINATOR);
return result;
}
}
public Serializable[] getPropertySpaces() {
return spaces;
}
//Access cached SQL
protected boolean isDiscriminatorFormula() {
return discriminatorColumnName==null;
}
protected String getDiscriminatorFormula() {
return discriminatorFormula;
}
protected String getTableName(int j) {
return qualifiedTableNames[j];
}
protected String[] getKeyColumns(int j) {
return keyColumnNames[j];
}
protected boolean isTableCascadeDeleteEnabled(int j) {
return cascadeDeleteEnabled[j];
}
protected boolean isPropertyOfTable(int property, int j) {
return propertyTableNumbers[property]==j;
}
protected boolean isSubclassTableSequentialSelect(int j) {
return subclassTableSequentialSelect[j] && !isClassOrSuperclassTable[j];
}
// Execute the SQL:
public String fromTableFragment(String name) {
return getTableName() + ' ' + name;
}
public String filterFragment(String alias) throws MappingException {
String result = discriminatorFilterFragment(alias);
if ( hasWhere() ) result += " and " + getSQLWhereString(alias);
return result;
}
public String oneToManyFilterFragment(String alias) throws MappingException {
return forceDiscriminator ?
discriminatorFilterFragment(alias) :
"";
}
private String discriminatorFilterFragment(String alias) throws MappingException {
if ( needsDiscriminator() ) {
InFragment frag = new InFragment();
if ( isDiscriminatorFormula() ) {
frag.setFormula( alias, getDiscriminatorFormulaTemplate() );
}
else {
frag.setColumn( alias, getDiscriminatorColumnName() );
}
String[] subclasses = getSubclassClosure();
for ( int i=0; i 1;
}
public String[] getConstraintOrderedTableNameClosure() {
return constraintOrderedTableNames;
}
public String[][] getContraintOrderedTableKeyColumnClosure() {
return constraintOrderedKeyColumnNames;
}
@Override
public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) {
return new DynamicFilterAliasGenerator(qualifiedTableNames, rootAlias);
}
}