HHH-7322 : Integrate one-to-many cascade and fetch mode to persisters

This commit is contained in:
Gail Badner 2012-06-06 12:42:55 -07:00
parent 92c7b2d04f
commit 503949b563
2 changed files with 153 additions and 99 deletions

View File

@ -99,6 +99,10 @@ import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.Fetchable;
import org.hibernate.metamodel.spi.binding.PluralAttributeAssociationElementBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding;
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
@ -160,7 +164,7 @@ public abstract class AbstractEntityPersister
private final boolean hasSubselectLoadableCollections;
protected final String rowIdName;
private final Set lazyProperties;
private final Set<String> lazyProperties;
// The optional SQL string defined in the where attribute
private final String sqlWhereString;
@ -566,13 +570,13 @@ public abstract class AbstractEntityPersister
propertySelectable = new boolean[hydrateSpan];
propertyColumnUpdateable = new boolean[hydrateSpan][];
propertyColumnInsertable = new boolean[hydrateSpan][];
HashSet thisClassProperties = new HashSet();
Set<Property> thisClassProperties = new HashSet<Property>();
lazyProperties = new HashSet();
ArrayList lazyNames = new ArrayList();
ArrayList lazyNumbers = new ArrayList();
ArrayList lazyTypes = new ArrayList();
ArrayList lazyColAliases = new ArrayList();
lazyProperties = new HashSet<String>();
List<String> lazyNames = new ArrayList<String>();
List<Integer> lazyNumbers = new ArrayList<Integer>();
List<Type> lazyTypes = new ArrayList<Type>();
List<String[]> lazyColAliases = new ArrayList<String[]>();
iter = persistentClass.getPropertyClosureIterator();
i = 0;
@ -865,13 +869,14 @@ public abstract class AbstractEntityPersister
propertySelectable = new boolean[hydrateSpan];
propertyColumnUpdateable = new boolean[hydrateSpan][];
propertyColumnInsertable = new boolean[hydrateSpan][];
HashSet thisClassProperties = new HashSet();
Set<AttributeBinding> thisClassProperties = new HashSet<AttributeBinding>();
lazyProperties = new HashSet<String>();
List<String> lazyNames = new ArrayList<String>();
List<Integer> lazyNumbers = new ArrayList<Integer>();
List<Type> lazyTypes = new ArrayList<Type>();
List<String[]> lazyColAliases = new ArrayList<String[]>();
lazyProperties = new HashSet();
ArrayList lazyNames = new ArrayList();
ArrayList lazyNumbers = new ArrayList();
ArrayList lazyTypes = new ArrayList();
ArrayList lazyColAliases = new ArrayList();
i = 0;
boolean foundFormula = false;
@ -940,10 +945,7 @@ public abstract class AbstractEntityPersister
lazyColAliases.add( colAliases );
}
// TODO: fix this when backrefs are working
//propertySelectable[i] = singularAttributeBinding.isBackRef();
propertySelectable[i] = true;
propertySelectable[i] = !attributeBinding.isBackRef();
propertyUniqueness[i] = attributeBinding.isAlternateUniqueKey();
@ -987,21 +989,25 @@ public abstract class AbstractEntityPersister
continue;
}
if ( ! attributeBinding.getAttribute().isSingular() ) {
// collections handled separately
continue;
}
final SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding;
names.add( singularAttributeBinding.getAttribute().getName() );
classes.add( ( (EntityBinding) singularAttributeBinding.getContainer() ).getEntity().getName() );
boolean isDefinedBySubclass = ! thisClassProperties.contains( singularAttributeBinding );
names.add( attributeBinding.getAttribute().getName() );
classes.add( ( (EntityBinding) attributeBinding.getContainer() ).getEntity().getName() );
boolean isDefinedBySubclass = ! thisClassProperties.contains( attributeBinding );
definedBySubclass.add( isDefinedBySubclass );
propNullables.add( singularAttributeBinding.isNullable() || isDefinedBySubclass ); //TODO: is this completely correct?
types.add( singularAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
// TODOFix this when join tables are supported...
//propNullables.add( attributeBinding.isOptional() || isDefinedBySubclass );
propNullables.add(
! attributeBinding.getAttribute().isSingular() ||
( (SingularAttributeBinding) attributeBinding).isNullable() ||
isDefinedBySubclass
);
types.add( attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
final int span = singularAttributeBinding.getRelationalValueBindings().size();
List<RelationalValueBinding> relationalValueBindings =
attributeBinding.getAttribute().isSingular() ?
( (SingularAttributeBinding) attributeBinding ).getRelationalValueBindings() :
null;
final int span = relationalValueBindings == null ? 0 : relationalValueBindings.size();
String[] cols = new String[ span ];
String[] readers = new String[ span ];
String[] readerTemplates = new String[ span ];
@ -1009,8 +1015,10 @@ public abstract class AbstractEntityPersister
int[] colnos = new int[ span ];
int[] formnos = new int[ span ];
int l = 0;
Boolean lazy = singularAttributeBinding.isLazy() && lazyAvailable;
for ( RelationalValueBinding valueBinding : singularAttributeBinding.getRelationalValueBindings() ) {
Boolean lazy = attributeBinding.isLazy() && lazyAvailable;
if ( relationalValueBindings != null ) {
for ( RelationalValueBinding valueBinding : relationalValueBindings ) {
if ( valueBinding.isDerived() ) {
DerivedValue derivedValue = DerivedValue.class.cast( valueBinding.getValue() );
String template = getTemplateFromString( derivedValue.getExpression(), factory );
@ -1036,8 +1044,7 @@ public abstract class AbstractEntityPersister
)
);
columnsLazy.add( lazy );
// TODO: properties only selectable if they are non-plural???
columnSelectables.add( singularAttributeBinding.getAttribute().isSingular() );
columnSelectables.add( ! attributeBinding.isBackRef() );
readers[l] =
col.getReadFragment() == null ?
@ -1049,6 +1056,7 @@ public abstract class AbstractEntityPersister
}
l++;
}
}
propColumns.add( cols );
propColumnReaders.add( readers );
propColumnReaderTemplates.add( readerTemplates );
@ -1056,14 +1064,26 @@ public abstract class AbstractEntityPersister
propColumnNumbers.add( colnos );
propFormulaNumbers.add( formnos );
if ( singularAttributeBinding.isAssociation() ) {
SingularAssociationAttributeBinding associationAttributeBinding =
(SingularAssociationAttributeBinding) singularAttributeBinding;
cascades.add( associationAttributeBinding.getCascadeStyle() );
joinedFetchesList.add( associationAttributeBinding.getFetchMode() );
CascadeStyle cascadeStyle = null;
if ( attributeBinding.isAssociation() ) {
if ( attributeBinding.getAttribute().isSingular() ) {
cascadeStyle = ( ( SingularAssociationAttributeBinding) attributeBinding ).getCascadeStyle();
}
else {
PluralAttributeElementBinding pluralAttributeElementBinding =
( (PluralAttributeBinding) attributeBinding ).getPluralAttributeElementBinding();
cascadeStyle = ( (PluralAttributeAssociationElementBinding) pluralAttributeElementBinding).getCascadeStyle();
}
}
if ( cascadeStyle == null ) {
cascadeStyle = CascadeStyle.NONE;
}
cascades.add( cascadeStyle );
if ( attributeBinding instanceof Fetchable ) {
joinedFetchesList.add( ( (Fetchable) attributeBinding ).getFetchMode() );
}
else {
cascades.add( CascadeStyle.NONE );
joinedFetchesList.add( FetchMode.SELECT );
}
}
@ -1204,7 +1224,9 @@ public abstract class AbstractEntityPersister
final Serializable id,
final EntityEntry entry) {
if ( !hasLazyProperties() ) throw new AssertionFailure( "no lazy properties" );
if ( !hasLazyProperties() ) {
throw new AssertionFailure( "no lazy properties" );
}
LOG.trace( "Initializing lazy properties from datastore" );
@ -1673,9 +1695,13 @@ public abstract class AbstractEntityPersister
}
Object nextVersion = getVersionType().next( currentVersion, session );
if (LOG.isTraceEnabled()) LOG.trace("Forcing version increment [" + MessageHelper.infoString(this, id, getFactory()) + "; "
+ getVersionType().toLoggableString(currentVersion, getFactory()) + " -> "
+ getVersionType().toLoggableString(nextVersion, getFactory()) + "]");
if ( LOG.isTraceEnabled() ) {
LOG.trace(
"Forcing version increment [" + MessageHelper.infoString( this, id, getFactory() ) + "; "
+ getVersionType().toLoggableString( currentVersion, getFactory() ) + " -> "
+ getVersionType().toLoggableString( nextVersion, getFactory() ) + "]"
);
}
// todo : cache this sql...
String versionIncrementString = generateVersionIncrementUpdateString();
@ -2866,9 +2892,10 @@ public abstract class AbstractEntityPersister
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Inserting entity: {0}", MessageHelper.infoString( this, id, getFactory() ) );
if ( j == 0 && isVersioned() )
if ( j == 0 && isVersioned() ) {
LOG.tracev( "Version: {0}", Versioning.getVersion( fields, this ) );
}
}
// TODO : shouldn't inserts be Expectations.NONE?
final Expectation expectation = Expectations.appropriateExpectation( insertResultCheckStyles[j] );
@ -3009,9 +3036,10 @@ public abstract class AbstractEntityPersister
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Updating entity: {0}", MessageHelper.infoString( this, id, getFactory() ) );
if ( useVersion )
if ( useVersion ) {
LOG.tracev( "Existing version: {0} -> New version:{1}", oldVersion, fields[getVersionProperty()] );
}
}
try {
int index = 1; // starting index
@ -3127,9 +3155,10 @@ public abstract class AbstractEntityPersister
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Deleting entity: {0}", MessageHelper.infoString( this, id, getFactory() ) );
if ( useVersion )
if ( useVersion ) {
LOG.tracev( "Version: {0}", version );
}
}
if ( isTableCascadeDeleteEnabled( j ) ) {
if ( LOG.isTraceEnabled() ) {
@ -3434,24 +3463,50 @@ public abstract class AbstractEntityPersister
protected void logStaticSQL() {
if (LOG.isDebugEnabled()) {
LOG.debugf("Static SQL for entity: %s", getEntityName());
if (sqlLazySelectString != null) LOG.debugf(" Lazy select: %s", sqlLazySelectString);
if (sqlVersionSelectString != null) LOG.debugf(" Version select: %s", sqlVersionSelectString);
if (sqlSnapshotSelectString != null) LOG.debugf(" Snapshot select: %s", sqlSnapshotSelectString);
if ( sqlLazySelectString != null ) {
LOG.debugf( " Lazy select: %s", sqlLazySelectString );
}
if ( sqlVersionSelectString != null ) {
LOG.debugf( " Version select: %s", sqlVersionSelectString );
}
if ( sqlSnapshotSelectString != null ) {
LOG.debugf( " Snapshot select: %s", sqlSnapshotSelectString );
}
for ( int j = 0; j < getTableSpan(); j++ ) {
LOG.debugf(" Insert %s: %s", j, getSQLInsertStrings()[j]);
LOG.debugf(" Update %s: %s", j, getSQLUpdateStrings()[j]);
LOG.debugf(" Delete %s: %s", j, getSQLDeleteStrings()[j]);
}
if (sqlIdentityInsertString != null) LOG.debugf(" Identity insert: %s", sqlIdentityInsertString);
if (sqlUpdateByRowIdString != null) LOG.debugf(" Update by row id (all fields): %s", sqlUpdateByRowIdString);
if (sqlLazyUpdateByRowIdString != null) LOG.debugf(" Update by row id (non-lazy fields): %s",
sqlLazyUpdateByRowIdString);
if (sqlInsertGeneratedValuesSelectString != null) LOG.debugf("Insert-generated property select: %s",
sqlInsertGeneratedValuesSelectString);
if (sqlUpdateGeneratedValuesSelectString != null) LOG.debugf("Update-generated property select: %s",
sqlUpdateGeneratedValuesSelectString);
if (sqlEntityIdByNaturalIdString != null) LOG.debugf("Id by Natural Id: %s",
sqlEntityIdByNaturalIdString);
if ( sqlIdentityInsertString != null ) {
LOG.debugf( " Identity insert: %s", sqlIdentityInsertString );
}
if ( sqlUpdateByRowIdString != null ) {
LOG.debugf( " Update by row id (all fields): %s", sqlUpdateByRowIdString );
}
if ( sqlLazyUpdateByRowIdString != null ) {
LOG.debugf(
" Update by row id (non-lazy fields): %s",
sqlLazyUpdateByRowIdString
);
}
if ( sqlInsertGeneratedValuesSelectString != null ) {
LOG.debugf(
"Insert-generated property select: %s",
sqlInsertGeneratedValuesSelectString
);
}
if ( sqlUpdateGeneratedValuesSelectString != null ) {
LOG.debugf(
"Update-generated property select: %s",
sqlUpdateGeneratedValuesSelectString
);
}
if ( sqlEntityIdByNaturalIdString != null ) {
LOG.debugf(
"Id by Natural Id: %s",
sqlEntityIdByNaturalIdString
);
}
}
}

View File

@ -129,13 +129,12 @@ public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
}
private PropertyAccessor buildPropertyAccessor(AttributeBinding mappedProperty) {
// TODO: fix when backrefs are working in new metamodel
//if ( mappedProperty.isBackRef() ) {
// return mappedProperty.getPropertyAccessor( null );
//}
//else {
if ( mappedProperty.isBackRef() ) {
return PropertyAccessorFactory.getPropertyAccessor( null, mappedProperty.getPropertyAccessorName() );
}
else {
return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
//}
}
}
/**