HHH-7240 - Develop identifier handling in new metamodel
This commit is contained in:
parent
a39b1a3a92
commit
5946391477
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.spi.binding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
|
@ -42,7 +44,7 @@ import org.hibernate.metamodel.spi.relational.Column;
|
|||
public class EntityIdentifier {
|
||||
private final EntityBinding entityBinding;
|
||||
|
||||
private BoundType boundType;
|
||||
private List<SingularAttributeBinding> identifierAttributeBindings = new ArrayList<SingularAttributeBinding>();
|
||||
|
||||
private IdGenerator idGenerator;
|
||||
private String unsavedValue;
|
||||
|
@ -50,9 +52,7 @@ public class EntityIdentifier {
|
|||
private Class idClassClass; // the class named in @IdClass
|
||||
|
||||
private IdentifierGenerator identifierGenerator;
|
||||
|
||||
private SingularNonAssociationAttributeBinding attributeBinding;
|
||||
private List<SingularAttributeBinding> nonAggregatedCompositeAttributeBindings;
|
||||
private int columnCount;
|
||||
|
||||
/**
|
||||
* Create an identifier
|
||||
|
@ -67,13 +67,11 @@ public class EntityIdentifier {
|
|||
SingularNonAssociationAttributeBinding attributeBinding,
|
||||
IdGenerator idGenerator,
|
||||
String unsavedValue) {
|
||||
if ( boundType != null ) {
|
||||
throw new IllegalStateException( "Entity identifier was already bound" );
|
||||
}
|
||||
this.boundType = BoundType.SINGLE_ATTRIBUTE;
|
||||
this.attributeBinding = attributeBinding;
|
||||
ensureNotBound();
|
||||
identifierAttributeBindings.add( attributeBinding );
|
||||
this.idGenerator = idGenerator;
|
||||
this.unsavedValue = unsavedValue;
|
||||
this.columnCount = attributeBinding.getRelationalValueBindings().size();
|
||||
|
||||
// Configure primary key in relational model
|
||||
for ( final RelationalValueBinding valueBinding : attributeBinding.getRelationalValueBindings() ) {
|
||||
|
@ -81,23 +79,52 @@ public class EntityIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
private void ensureNotBound() {
|
||||
if ( ! identifierAttributeBindings.isEmpty() ) {
|
||||
throw new IllegalStateException( "Entity identifier was already bound" );
|
||||
}
|
||||
}
|
||||
|
||||
public void bindAsMultipleAttributeIdentifier(
|
||||
List<SingularAttributeBinding> nonAggregatedCompositeAttributeBindings,
|
||||
Class idClassClass) {
|
||||
if ( boundType != null ) {
|
||||
throw new IllegalStateException( "Entity identifier was already bound" );
|
||||
ensureNotBound();
|
||||
for ( SingularAttributeBinding attributeBinding : nonAggregatedCompositeAttributeBindings ) {
|
||||
identifierAttributeBindings.add( attributeBinding );
|
||||
columnCount += attributeBinding.getRelationalValueBindings().size();
|
||||
|
||||
// Configure primary key in relational model
|
||||
for ( final RelationalValueBinding valueBinding : attributeBinding.getRelationalValueBindings() ) {
|
||||
entityBinding.getPrimaryTable().getPrimaryKey().addColumn( (Column) valueBinding.getValue() );
|
||||
}
|
||||
}
|
||||
this.boundType = BoundType.MULTIPLE_ATTRIBUTE;
|
||||
this.nonAggregatedCompositeAttributeBindings = nonAggregatedCompositeAttributeBindings;
|
||||
this.idClassClass = idClassClass;
|
||||
}
|
||||
|
||||
public SingularNonAssociationAttributeBinding getValueBinding() {
|
||||
return attributeBinding;
|
||||
public boolean isSingleAttribute() {
|
||||
ensureBound();
|
||||
return identifierAttributeBindings.size() == 1;
|
||||
}
|
||||
|
||||
public List<SingularAttributeBinding> getNonAggregatedCompositeAttributeBindings() {
|
||||
return nonAggregatedCompositeAttributeBindings;
|
||||
public List<SingularAttributeBinding> getIdentifierAttributeBindings() {
|
||||
return Collections.unmodifiableList( identifierAttributeBindings );
|
||||
}
|
||||
|
||||
public boolean isIdentifierAttributeBinding(AttributeBinding attributeBinding) {
|
||||
for ( SingularAttributeBinding identifierAttributeBinding : identifierAttributeBindings ) {
|
||||
if ( identifierAttributeBinding.equals( attributeBinding ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected SingularNonAssociationAttributeBinding getSingleIdentifierAttributeBinding() {
|
||||
if ( ! isSingleAttribute() ) {
|
||||
throw new IllegalStateException( "Entity identifier is made up of multiple attributes" );
|
||||
}
|
||||
|
||||
return (SingularNonAssociationAttributeBinding) identifierAttributeBindings.get( 0 );
|
||||
}
|
||||
|
||||
public String getUnsavedValue() {
|
||||
|
@ -105,7 +132,7 @@ public class EntityIdentifier {
|
|||
}
|
||||
|
||||
public boolean isEmbedded() {
|
||||
return boundType == BoundType.SINGLE_ATTRIBUTE && attributeBinding.getRelationalValueBindings().size() > 1;
|
||||
return isSingleAttribute() && columnCount > 1;
|
||||
}
|
||||
|
||||
public Class getIdClassClass() {
|
||||
|
@ -113,25 +140,39 @@ public class EntityIdentifier {
|
|||
}
|
||||
|
||||
public boolean isIdentifierMapper() {
|
||||
// i think
|
||||
return boundType == BoundType.MULTIPLE_ATTRIBUTE && idClassClass != null;
|
||||
// i think this is the intended check for this method
|
||||
return ! isSingleAttribute() && idClassClass != null;
|
||||
}
|
||||
|
||||
// todo do we really need this createIdentifierGenerator and how do we make sure the getter is not called too early
|
||||
// maybe some sort of visitor pattern here!? (HF)
|
||||
public IdentifierGenerator createIdentifierGenerator(IdentifierGeneratorFactory factory, Properties properties) {
|
||||
if ( idGenerator != null ) {
|
||||
identifierGenerator = attributeBinding.createIdentifierGenerator( idGenerator, factory, properties );
|
||||
ensureBound();
|
||||
if ( identifierGenerator == null ) {
|
||||
if ( isSingleAttribute() && idGenerator != null ) {
|
||||
identifierGenerator = getSingleIdentifierAttributeBinding().createIdentifierGenerator(
|
||||
idGenerator,
|
||||
factory,
|
||||
properties
|
||||
);
|
||||
}
|
||||
}
|
||||
return identifierGenerator;
|
||||
}
|
||||
|
||||
public IdentifierGenerator getIdentifierGenerator() {
|
||||
ensureBound();
|
||||
return identifierGenerator;
|
||||
}
|
||||
|
||||
private static enum BoundType {
|
||||
SINGLE_ATTRIBUTE,
|
||||
MULTIPLE_ATTRIBUTE
|
||||
protected void ensureBound() {
|
||||
if ( identifierAttributeBindings.isEmpty() ) {
|
||||
throw new IllegalStateException( "Entity identifier was not yet bound" );
|
||||
}
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
ensureBound();
|
||||
return columnCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -775,14 +775,11 @@ public abstract class AbstractEntityPersister
|
|||
final SessionFactoryImplementor factory) throws HibernateException {
|
||||
this.factory = factory;
|
||||
this.cacheAccessStrategy = cacheAccessStrategy;
|
||||
this.isLazyPropertiesCacheable =
|
||||
entityBinding.getHierarchyDetails().getCaching() == null ?
|
||||
false :
|
||||
entityBinding.getHierarchyDetails().getCaching().isCacheLazyProperties();
|
||||
this.cacheEntryStructure =
|
||||
factory.getSettings().isStructuredCacheEntriesEnabled() ?
|
||||
new StructuredCacheEntry(this) :
|
||||
new UnstructuredCacheEntry();
|
||||
this.isLazyPropertiesCacheable = entityBinding.getHierarchyDetails().getCaching() != null
|
||||
&& entityBinding.getHierarchyDetails().getCaching().isCacheLazyProperties();
|
||||
this.cacheEntryStructure = factory.getSettings().isStructuredCacheEntriesEnabled()
|
||||
? new StructuredCacheEntry(this)
|
||||
: new UnstructuredCacheEntry();
|
||||
this.entityMetamodel = new EntityMetamodel( entityBinding, factory );
|
||||
this.entityTuplizer = this.entityMetamodel.getTuplizer();
|
||||
int batch = entityBinding.getBatchSize();
|
||||
|
@ -791,24 +788,20 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
batchSize = batch;
|
||||
hasSubselectLoadableCollections = entityBinding.hasSubselectLoadableCollections();
|
||||
rowIdName = entityBinding.getRowId();
|
||||
loaderName = entityBinding.getCustomLoaderName();
|
||||
|
||||
propertyMapping = new BasicEntityPropertyMapping( this );
|
||||
|
||||
|
||||
// IDENTIFIER
|
||||
|
||||
identifierColumnSpan = entityBinding.getHierarchyDetails()
|
||||
.getEntityIdentifier()
|
||||
.getValueBinding()
|
||||
.getRelationalValueBindings()
|
||||
.size();
|
||||
identifierColumnSpan = entityBinding.getHierarchyDetails().getEntityIdentifier().getColumnCount();
|
||||
rootTableKeyColumnNames = new String[identifierColumnSpan];
|
||||
rootTableKeyColumnReaders = new String[identifierColumnSpan];
|
||||
rootTableKeyColumnReaderTemplates = new String[identifierColumnSpan];
|
||||
identifierAliases = new String[identifierColumnSpan];
|
||||
|
||||
rowIdName = entityBinding.getRowId();
|
||||
|
||||
loaderName = entityBinding.getCustomLoaderName();
|
||||
|
||||
int i = 0;
|
||||
for ( org.hibernate.metamodel.spi.relational.Column col : entityBinding.getPrimaryTable().getPrimaryKey().getColumns() ) {
|
||||
|
@ -882,7 +875,7 @@ public abstract class AbstractEntityPersister
|
|||
i = 0;
|
||||
boolean foundFormula = false;
|
||||
for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) {
|
||||
if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) {
|
||||
if ( entityBinding.getHierarchyDetails().getEntityIdentifier().isIdentifierAttributeBinding( attributeBinding ) ) {
|
||||
// entity identifier is not considered a "normal" property
|
||||
continue;
|
||||
}
|
||||
|
@ -985,7 +978,7 @@ public abstract class AbstractEntityPersister
|
|||
List<Boolean> propNullables = new ArrayList<Boolean>();
|
||||
|
||||
for ( AttributeBinding attributeBinding : entityBinding.getSubEntityAttributeBindingClosure() ) {
|
||||
if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) {
|
||||
if ( entityBinding.getHierarchyDetails().getEntityIdentifier().isIdentifierAttributeBinding( attributeBinding ) ) {
|
||||
// entity identifier is not considered a "normal" property
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -619,7 +619,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
|||
for( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) {
|
||||
// TODO: fix when joins are working (HHH-6391)
|
||||
//propertyTableNumbers[i++] = entityBinding.getJoinNumber( attributeBinding);
|
||||
if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) {
|
||||
if ( entityBinding.getHierarchyDetails().getEntityIdentifier().isIdentifierAttributeBinding( attributeBinding ) ) {
|
||||
continue; // skip identifier binding
|
||||
}
|
||||
if ( ! attributeBinding.getAttribute().isSingular() ) {
|
||||
|
|
|
@ -426,7 +426,7 @@ public class EntityMetamodel implements Serializable {
|
|||
boolean foundUpdateableNaturalIdProperty = false;
|
||||
|
||||
for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) {
|
||||
if ( attributeBinding == rootEntityIdentifier ) {
|
||||
if ( entityBinding.getHierarchyDetails().getEntityIdentifier().isIdentifierAttributeBinding( attributeBinding ) ) {
|
||||
// skip the identifier attribute binding
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue