HHH-6447 - Develop shared binding creation approach

This commit is contained in:
Steve Ebersole 2011-07-20 15:31:18 -05:00
parent 4968ad11fb
commit acc93a3d8c
70 changed files with 1562 additions and 1005 deletions

View File

@ -28,8 +28,8 @@ import java.util.Comparator;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.type.VersionType;
/**
@ -84,7 +84,7 @@ public class CacheDataDescriptionImpl implements CacheDataDescription {
);
}
public static CacheDataDescriptionImpl decode(PluralAttributeBinding model) {
public static CacheDataDescriptionImpl decode(AbstractPluralAttributeBinding model) {
return new CacheDataDescriptionImpl(
model.isMutable(),
model.getEntityBinding().isVersioned(),

View File

@ -114,7 +114,7 @@ import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
@ -661,16 +661,16 @@ public final class SessionFactoryImpl
Map<String,Set<String>> tmpEntityToCollectionRoleMap = new HashMap<String,Set<String>>();
collectionPersisters = new HashMap();
for ( PluralAttributeBinding model : metadata.getCollectionBindings() ) {
for ( AbstractPluralAttributeBinding model : metadata.getCollectionBindings() ) {
if ( model.getAttribute() == null ) {
throw new IllegalStateException( "No attribute defined for a PluralAttributeBinding: " + model );
throw new IllegalStateException( "No attribute defined for a AbstractPluralAttributeBinding: " + model );
}
if ( model.getAttribute().isSingular() ) {
throw new IllegalStateException(
"PluralAttributeBinding has a Singular attribute defined: " + model.getAttribute().getName()
"AbstractPluralAttributeBinding has a Singular attribute defined: " + model.getAttribute().getName()
);
}
// TODO: Add PluralAttributeBinding.getCaching()
// TODO: Add AbstractPluralAttributeBinding.getCaching()
final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
final AccessType accessType = AccessType.fromExternalName( model.getCacheConcurrencyStrategy() );
CollectionRegionAccessStrategy accessStrategy = null;

View File

@ -37,7 +37,7 @@ import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
/**
@ -75,7 +75,7 @@ public interface Metadata {
*/
public EntityBinding getRootEntityBinding(String entityName);
public Iterable<PluralAttributeBinding> getCollectionBindings();
public Iterable<AbstractPluralAttributeBinding> getCollectionBindings();
public TypeDef getTypeDefinition(String name);

View File

@ -29,19 +29,12 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.MappingException;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.binding.state.AttributeBindingState;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.DerivedValue;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Tuple;
import org.hibernate.metamodel.relational.Value;
import org.hibernate.metamodel.relational.state.SimpleValueRelationalState;
import org.hibernate.metamodel.relational.state.TupleRelationalState;
import org.hibernate.metamodel.relational.state.ValueCreator;
import org.hibernate.metamodel.relational.state.ValueRelationalState;
import org.hibernate.metamodel.source.MetaAttributeContext;
/**
* Basic support for {@link AttributeBinding} implementors
@ -50,23 +43,22 @@ import org.hibernate.metamodel.relational.state.ValueRelationalState;
*/
public abstract class AbstractAttributeBinding implements AttributeBinding {
private final EntityBinding entityBinding;
private final Attribute attribute;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final Set<SingularAssociationAttributeBinding> entityReferencingAttributeBindings = new HashSet<SingularAssociationAttributeBinding>();
private Attribute attribute;
private Value value;
private boolean includedInOptimisticLocking;
private boolean isLazy;
private String propertyAccessorName;
private boolean isAlternateUniqueKey;
private Set<CascadeType> cascadeTypes;
private boolean optimisticLockable;
private MetaAttributeContext metaAttributeContext;
protected AbstractAttributeBinding(EntityBinding entityBinding) {
protected AbstractAttributeBinding(EntityBinding entityBinding, Attribute attribute) {
this.entityBinding = entityBinding;
this.attribute = attribute;
}
protected void initialize(AttributeBindingState state) {
@ -74,10 +66,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
hibernateTypeDescriptor.setTypeParameters( state.getExplicitHibernateTypeParameters() );
hibernateTypeDescriptor.setJavaTypeName( state.getJavaTypeName() );
isLazy = state.isLazy();
propertyAccessorName = state.getPropertyAccessorName();
isAlternateUniqueKey = state.isAlternateUniqueKey();
cascadeTypes = state.getCascadeTypes();
optimisticLockable = state.isOptimisticLockable();
metaAttributeContext = state.getMetaAttributeContext();
}
@ -91,12 +80,32 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
return attribute;
}
protected void setAttribute(Attribute attribute) {
this.attribute = attribute;
@Override
public HibernateTypeDescriptor getHibernateTypeDescriptor() {
return hibernateTypeDescriptor;
}
public void setValue(Value value) {
this.value = value;
@Override
public boolean isBasicPropertyAccessor() {
return propertyAccessorName == null || "property".equals( propertyAccessorName );
}
@Override
public String getPropertyAccessorName() {
return propertyAccessorName;
}
public void setPropertyAccessorName(String propertyAccessorName) {
this.propertyAccessorName = propertyAccessorName;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return includedInOptimisticLocking;
}
public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking) {
this.includedInOptimisticLocking = includedInOptimisticLocking;
}
protected boolean forceNonNullable() {
@ -111,100 +120,13 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
return this == getEntityBinding().getEntityIdentifier().getValueBinding();
}
protected void initializeValueRelationalState(ValueRelationalState state) {
// TODO: change to have ValueRelationalState generate the value
value = ValueCreator.createValue(
getEntityBinding().getBaseTable(),
getAttribute().getName(),
state,
forceNonNullable(),
forceUnique()
);
// TODO: not sure I like this here...
if ( isPrimaryKey() ) {
if ( SimpleValue.class.isInstance( value ) ) {
if ( !Column.class.isInstance( value ) ) {
// this should never ever happen..
throw new MappingException( "Simple ID is not a column." );
}
entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( value ) );
}
else {
for ( SimpleValueRelationalState val : TupleRelationalState.class.cast( state )
.getRelationalStates() ) {
if ( Column.class.isInstance( val ) ) {
entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( val ) );
}
}
}
}
}
@Override
public Value getValue() {
return value;
}
@Override
public HibernateTypeDescriptor getHibernateTypeDescriptor() {
return hibernateTypeDescriptor;
}
public Set<CascadeType> getCascadeTypes() {
return cascadeTypes;
}
public boolean isOptimisticLockable() {
return optimisticLockable;
}
@Override
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}
@Override
public int getValuesSpan() {
if ( value == null ) {
return 0;
}
else if ( value instanceof Tuple ) {
return ( ( Tuple ) value ).valuesSpan();
}
else {
return 1;
}
}
@Override
public Iterable<SimpleValue> getValues() {
return value == null
? Collections.<SimpleValue>emptyList()
: value instanceof Tuple
? ( (Tuple) value ).values()
: Collections.singletonList( (SimpleValue) value );
}
@Override
public String getPropertyAccessorName() {
return propertyAccessorName;
}
@Override
public boolean isBasicPropertyAccessor() {
return propertyAccessorName==null || "property".equals( propertyAccessorName );
}
@Override
public boolean hasFormula() {
for ( SimpleValue simpleValue : getValues() ) {
if ( simpleValue instanceof DerivedValue ) {
return true;
}
}
return false;
public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) {
this.metaAttributeContext = metaAttributeContext;
}
@Override
@ -216,39 +138,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
this.isAlternateUniqueKey = alternateUniqueKey;
}
@Override
public boolean isNullable() {
for ( SimpleValue simpleValue : getValues() ) {
if ( simpleValue instanceof DerivedValue ) {
return true;
}
Column column = (Column) simpleValue;
if ( column.isNullable() ) {
return true;
}
}
return false;
}
@Override
public boolean[] getColumnInsertability() {
List<Boolean> tmp = new ArrayList<Boolean>();
for ( SimpleValue simpleValue : getValues() ) {
tmp.add( !( simpleValue instanceof DerivedValue ) );
}
boolean[] rtn = new boolean[tmp.size()];
int i = 0;
for ( Boolean insertable : tmp ) {
rtn[i++] = insertable.booleanValue();
}
return rtn;
}
@Override
public boolean[] getColumnUpdateability() {
return getColumnInsertability();
}
@Override
public boolean isLazy() {
return isLazy;

View File

@ -0,0 +1,298 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. 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 Inc.
*
* 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.metamodel.binding;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.relational.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBinding implements PluralAttributeBinding {
private CollectionKey collectionKey;
private CollectionElement collectionElement;
private Table collectionTable;
private CascadeStyle cascadeStyle;
private FetchMode fetchMode;
private boolean extraLazy;
private boolean inverse;
private boolean mutable = true;
private boolean subselectLoadable;
private String cacheConcurrencyStrategy;
private String cacheRegionName;
private String orderBy;
private String where;
private String referencedPropertyName;
private boolean sorted;
private Comparator comparator;
private String comparatorClassName;
private boolean orphanDelete;
private int batchSize = -1;
private boolean embedded = true;
private boolean optimisticLocked = true;
private Class collectionPersisterClass;
private final java.util.Map filters = new HashMap();
private final java.util.Set<String> synchronizedTables = new HashSet<String>();
private CustomSQL customSQLInsert;
private CustomSQL customSQLUpdate;
private CustomSQL customSQLDelete;
private CustomSQL customSQLDeleteAll;
private String loaderName;
protected AbstractPluralAttributeBinding(
EntityBinding entityBinding,
PluralAttribute attribute,
CollectionElementNature collectionElementNature) {
super( entityBinding, attribute );
this.collectionElement = interpretNature( collectionElementNature );
}
private CollectionElement interpretNature(CollectionElementNature collectionElementNature) {
switch ( collectionElementNature ) {
case BASIC: {
return new BasicCollectionElement( this );
}
case COMPOSITE: {
return new CompositeCollectionElement( this );
}
case ONE_TO_MANY: {
return new OneToManyCollectionElement( this );
}
case MANY_TO_MANY: {
return new ManyToManyCollectionElement( this );
}
case MANY_TO_ANY: {
return new ManyToAnyCollectionElement( this );
}
default: {
throw new AssertionFailure( "Unknown collection element nature : " + collectionElementNature );
}
}
}
// protected void initializeBinding(PluralAttributeBindingState state) {
// super.initialize( state );
// fetchMode = state.getFetchMode();
// extraLazy = state.isExtraLazy();
// collectionElement.setNodeName( state.getElementNodeName() );
// collectionElement.setTypeName( state.getElementTypeName() );
// inverse = state.isInverse();
// mutable = state.isMutable();
// subselectLoadable = state.isSubselectLoadable();
// if ( isSubselectLoadable() ) {
// getEntityBinding().setSubselectLoadableCollections( true );
// }
// cacheConcurrencyStrategy = state.getCacheConcurrencyStrategy();
// cacheRegionName = state.getCacheRegionName();
// orderBy = state.getOrderBy();
// where = state.getWhere();
// referencedPropertyName = state.getReferencedPropertyName();
// sorted = state.isSorted();
// comparator = state.getComparator();
// comparatorClassName = state.getComparatorClassName();
// orphanDelete = state.isOrphanDelete();
// batchSize = state.getBatchSize();
// embedded = state.isEmbedded();
// optimisticLocked = state.isOptimisticLocked();
// collectionPersisterClass = state.getCollectionPersisterClass();
// filters.putAll( state.getFilters() );
// synchronizedTables.addAll( state.getSynchronizedTables() );
// customSQLInsert = state.getCustomSQLInsert();
// customSQLUpdate = state.getCustomSQLUpdate();
// customSQLDelete = state.getCustomSQLDelete();
// customSQLDeleteAll = state.getCustomSQLDeleteAll();
// loaderName = state.getLoaderName();
// }
@Override
public boolean isAssociation() {
return collectionElement.getCollectionElementNature() == CollectionElementNature.MANY_TO_ANY
|| collectionElement.getCollectionElementNature() == CollectionElementNature.MANY_TO_MANY
|| collectionElement.getCollectionElementNature() == CollectionElementNature.ONE_TO_MANY;
}
public Table getCollectionTable() {
return collectionTable;
}
public void setCollectionTable(Table collectionTable) {
this.collectionTable = collectionTable;
}
public CollectionKey getCollectionKey() {
return collectionKey;
}
public void setCollectionKey(CollectionKey collectionKey) {
this.collectionKey = collectionKey;
}
public CollectionElement getCollectionElement() {
return collectionElement;
}
@Override
public CascadeStyle getCascadeStyle() {
return cascadeStyle;
}
@Override
public void setCascadeStyles(Iterable<CascadeStyle> cascadeStyles) {
List<CascadeStyle> cascadeStyleList = new ArrayList<CascadeStyle>();
for ( CascadeStyle style : cascadeStyles ) {
if ( style != CascadeStyle.NONE ) {
cascadeStyleList.add( style );
}
}
if ( cascadeStyleList.isEmpty() ) {
cascadeStyle = CascadeStyle.NONE;
}
else if ( cascadeStyleList.size() == 1 ) {
cascadeStyle = cascadeStyleList.get( 0 );
}
else {
cascadeStyle = new CascadeStyle.MultipleCascadeStyle(
cascadeStyleList.toArray( new CascadeStyle[ cascadeStyleList.size() ] )
);
}
}
@Override
public FetchMode getFetchMode() {
return fetchMode;
}
@Override
public void setFetchMode(FetchMode fetchMode) {
this.fetchMode = fetchMode;
}
public boolean isExtraLazy() {
return extraLazy;
}
public boolean isInverse() {
return inverse;
}
public boolean isMutable() {
return mutable;
}
public boolean isSubselectLoadable() {
return subselectLoadable;
}
public String getCacheConcurrencyStrategy() {
return cacheConcurrencyStrategy;
}
public String getCacheRegionName() {
return cacheRegionName;
}
public String getOrderBy() {
return orderBy;
}
public String getWhere() {
return where;
}
public String getReferencedPropertyName() {
return referencedPropertyName;
}
public boolean isSorted() {
return sorted;
}
public Comparator getComparator() {
return comparator;
}
public void setComparator(Comparator comparator) {
this.comparator = comparator;
}
public String getComparatorClassName() {
return comparatorClassName;
}
public boolean isOrphanDelete() {
return orphanDelete;
}
public int getBatchSize() {
return batchSize;
}
public Class getCollectionPersisterClass() {
return collectionPersisterClass;
}
public void addFilter(String name, String condition) {
filters.put( name, condition );
}
public java.util.Map getFilterMap() {
return filters;
}
public CustomSQL getCustomSQLInsert() {
return customSQLInsert;
}
public CustomSQL getCustomSQLUpdate() {
return customSQLUpdate;
}
public CustomSQL getCustomSQLDelete() {
return customSQLDelete;
}
public CustomSQL getCustomSQLDeleteAll() {
return customSQLDeleteAll;
}
public String getLoaderName() {
return loaderName;
}
}

View File

@ -0,0 +1,113 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc.
*
* 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.metamodel.binding;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Tuple;
import org.hibernate.metamodel.relational.Value;
/**
* @author Steve Ebersole
*/
public abstract class AbstractSingularAttributeBinding
extends AbstractAttributeBinding
implements SingularAttributeBinding {
private Value value;
private List<SimpleValueBinding> simpleValueBindings = new ArrayList<SimpleValueBinding>();
private boolean hasDerivedValue;
private boolean isNullable = true;
protected AbstractSingularAttributeBinding(EntityBinding entityBinding, SingularAttribute attribute) {
super( entityBinding, attribute );
}
@Override
public SingularAttribute getAttribute() {
return (SingularAttribute) super.getAttribute();
}
public Value getValue() {
return value;
}
public void setSimpleValueBindings(Iterable<SimpleValueBinding> simpleValueBindings) {
List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( SimpleValueBinding simpleValueBinding : simpleValueBindings ) {
this.simpleValueBindings.add( simpleValueBinding );
values.add( simpleValueBinding.getSimpleValue() );
this.hasDerivedValue = this.hasDerivedValue || simpleValueBinding.isDerived();
this.isNullable = this.isNullable && simpleValueBinding.isNullable();
}
if ( values.size() == 1 ) {
this.value = values.get( 0 );
}
else {
final Tuple tuple = values.get( 0 ).getTable().createTuple( getRole() );
for ( SimpleValue value : values ) {
tuple.addValue( value );
}
this.value = tuple;
}
}
private String getRole() {
return getEntityBinding().getEntity().getName() + '.' + getAttribute().getName();
}
@Override
public int getSimpleValueSpan() {
checkValueBinding();
return simpleValueBindings.size();
}
private void checkValueBinding() {
if ( value == null ) {
throw new AssertionFailure( "No values yet bound!" );
}
}
@Override
public Iterable<SimpleValueBinding> getSimpleValueBindings() {
return simpleValueBindings;
}
@Override
public boolean hasDerivedValue() {
checkValueBinding();
return hasDerivedValue;
}
@Override
public boolean isNullable() {
checkValueBinding();
return isNullable;
}
}

View File

@ -23,6 +23,7 @@
*/
package org.hibernate.metamodel.binding;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle;
/**
@ -32,11 +33,11 @@ import org.hibernate.engine.spi.CascadeStyle;
*/
public interface AssociationAttributeBinding extends AttributeBinding {
/**
* Obtain the cascade styles in effect for this association.
* Obtain the cascade style in effect for this association.
*
* @return THe cascade styles.
* @return The (potentially aggregated) cascade style.
*/
public Iterable<CascadeStyle> getCascadeStyles();
public CascadeStyle getCascadeStyle();
/**
* Set the cascade styles in effect for this association.
@ -44,4 +45,8 @@ public interface AssociationAttributeBinding extends AttributeBinding {
* @param cascadeStyles The cascade styles.
*/
public void setCascadeStyles(Iterable<CascadeStyle> cascadeStyles);
public FetchMode getFetchMode();
public void setFetchMode(FetchMode fetchMode);
}

View File

@ -25,13 +25,11 @@ package org.hibernate.metamodel.binding;
import java.util.Set;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Value;
import org.hibernate.metamodel.source.MetaAttributeContext;
/**
* The basic contract for binding between an {@link #getAttribute() attribute} and a {@link #getValue() value}
* The basic contract for binding a {@link #getAttribute() attribute} from the domain model to the relational model.
*
* @author Steve Ebersole
*/
@ -50,13 +48,6 @@ public interface AttributeBinding {
*/
public Attribute getAttribute();
/**
* Obtain the value bound
*
* @return The value
*/
public Value getValue();
/**
* Obtain the descriptor for the Hibernate {@link org.hibernate.type.Type} for this binding.
* <p/>
@ -67,6 +58,18 @@ public interface AttributeBinding {
*/
public HibernateTypeDescriptor getHibernateTypeDescriptor();
public boolean isAssociation();
public boolean isBasicPropertyAccessor();
public String getPropertyAccessorName();
public void setPropertyAccessorName(String propertyAccessorName);
public boolean isIncludedInOptimisticLocking();
public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking);
/**
* Obtain the meta attributes associated with this binding
*
@ -74,40 +77,10 @@ public interface AttributeBinding {
*/
public MetaAttributeContext getMetaAttributeContext();
/**
* Returns the number of {@link org.hibernate.metamodel.relational.SimpleValue}
* objects that will be returned by {@link #getValues()}
*
* @return the number of objects that will be returned by {@link #getValues()}.
*
* @see {@link org.hibernate.metamodel.relational.SimpleValue}
* @see {@link #getValues()}
*/
public int getValuesSpan();
/**
* @return In the case that {@link #getValue()} represents a {@link org.hibernate.metamodel.relational.Tuple} this method
* gives access to its compound values. In the case of {@link org.hibernate.metamodel.relational.SimpleValue},
* we return an Iterable over that single simple value.
*/
public Iterable<SimpleValue> getValues();
public String getPropertyAccessorName();
public boolean isBasicPropertyAccessor();
public boolean hasFormula();
public boolean isAlternateUniqueKey();
public boolean isNullable();
public boolean[] getColumnUpdateability();
public boolean[] getColumnInsertability();
public boolean isSimpleValue();
public boolean isLazy();
public void addEntityReferencingAttributeBinding(SingularAssociationAttributeBinding attributeBinding);

View File

@ -23,20 +23,15 @@
*/
package org.hibernate.metamodel.binding;
import org.hibernate.metamodel.binding.state.PluralAttributeBindingState;
import org.hibernate.metamodel.domain.PluralAttribute;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class BagBinding extends PluralAttributeBinding {
protected BagBinding(EntityBinding entityBinding, CollectionElementType collectionElementType) {
super( entityBinding, collectionElementType );
}
public BagBinding initialize(PluralAttributeBindingState bindingState) {
super.initialize( bindingState );
return this;
public class BagBinding extends AbstractPluralAttributeBinding {
protected BagBinding(EntityBinding entityBinding, PluralAttribute attribute, CollectionElementNature nature) {
super( entityBinding, attribute, nature );
}
}

View File

@ -27,7 +27,7 @@ package org.hibernate.metamodel.binding;
* @author Gail Badner
*/
public class BasicCollectionElement extends CollectionElement {
public BasicCollectionElement(PluralAttributeBinding binding) {
super( binding, CollectionElementType.BASIC );
public BasicCollectionElement(AbstractPluralAttributeBinding binding) {
super( binding, CollectionElementNature.BASIC );
}
}

View File

@ -31,39 +31,31 @@ import org.hibernate.metamodel.relational.Value;
* @author Steve Ebersole
*/
public abstract class CollectionElement {
private final AbstractPluralAttributeBinding collectionBinding;
private final CollectionElementNature collectionElementNature;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final PluralAttributeBinding collectionBinding;
private final CollectionElementType collectionElementType;
private String nodeName;
private Value elementValue;
CollectionElement(PluralAttributeBinding collectionBinding, CollectionElementType collectionElementType) {
CollectionElement(AbstractPluralAttributeBinding collectionBinding, CollectionElementNature collectionElementNature) {
this.collectionBinding = collectionBinding;
this.collectionElementType = collectionElementType;
this.collectionElementNature = collectionElementNature;
}
public final CollectionElementType getCollectionElementType() {
return collectionElementType;
public AbstractPluralAttributeBinding getCollectionBinding() {
return collectionBinding;
}
/* package-protected */
void setTypeName(String typeName) {
hibernateTypeDescriptor.setExplicitTypeName( typeName );
public Value getElementValue() {
return elementValue;
}
/* package-protected */
void setNodeName(String nodeName) {
this.nodeName = nodeName;
public final CollectionElementNature getCollectionElementNature() {
return collectionElementNature;
}
public boolean isOneToMany() {
return collectionElementType.isOneToMany();
public HibernateTypeDescriptor getHibernateTypeDescriptor() {
return hibernateTypeDescriptor;
}
public boolean isManyToMany() {
return collectionElementType.isManyToMany();
}
}

View File

@ -21,23 +21,20 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding.state;
import org.hibernate.mapping.PropertyGeneration;
package org.hibernate.metamodel.binding;
/**
* Describes the nature of persistent collection elements.
*
* @author Steve Ebersole
* @author Gail Badner
* @todo - We need to get a better split into the states. For example this SimpleAttributeBindingState contains
* state which is only relevant for primary/foreign keys. This should be in a different interface. (HF)
*
* @todo Merge with {@link org.hibernate.metamodel.source.binder.PluralAttributeNature} ? package separation kept me from doing that initially
*/
public interface SimpleAttributeBindingState extends AttributeBindingState {
boolean isInsertable();
boolean isUpdatable();
boolean isKeyCascadeDeleteEnabled();
String getUnsavedValue();
public PropertyGeneration getPropertyGeneration();
public enum CollectionElementNature {
BASIC,
COMPOSITE,
ONE_TO_MANY,
MANY_TO_MANY,
MANY_TO_ANY
}

View File

@ -1,104 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc.
*
* 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.metamodel.binding;
/**
* @author Gail Badner
*/
public enum CollectionElementType {
BASIC( "basic" ) {
public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) {
return new BasicCollectionElement( attributeBinding );
}
},
COMPOSITE( "composite" ) {
public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) {
return new CompositeCollectionElement( attributeBinding );
}
},
ONE_TO_MANY( "one-to-many" ) {
public boolean isOneToMany() {
return true;
}
public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) {
return new OneToManyCollectionElement( attributeBinding );
}
},
MANY_TO_MANY( "many-to-many" ) {
public boolean isManyToMany() {
return true;
}
public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) {
return new ManyToManyCollectionElement( attributeBinding );
}
},
MANY_TO_ANY( "many-to-any" ) {
//TODO: should isManyToMany() return true?
public boolean isManyToAny() {
return true;
}
public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) {
return new ManyToAnyCollectionElement( attributeBinding );
}
};
private final String name;
private CollectionElementType(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return super.toString() + "[" + getName() + "]";
}
public boolean isOneToMany() {
return false;
}
public boolean isManyToMany() {
return false;
}
public boolean isManyToAny() {
return false;
}
protected abstract CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding);
/* package-protected */
CollectionElement createCollectionElement(PluralAttributeBinding attributeBinding) {
CollectionElement collectionElement = createCollectionElementInternal( attributeBinding );
if ( collectionElement.getCollectionElementType() != this ) {
throw new IllegalStateException( "Collection element has unexpected type nature: actual=[" +
collectionElement.getCollectionElementType() + "; expected=[" + this + "]" );
}
return collectionElement;
}
}

View File

@ -31,16 +31,16 @@ import org.hibernate.metamodel.relational.ForeignKey;
* @author Steve Ebersole
*/
public class CollectionKey {
private final PluralAttributeBinding collection;
private final AbstractPluralAttributeBinding collection;
private ForeignKey foreignKey;
private boolean inverse;
private HibernateTypeDescriptor hibernateTypeDescriptor;
// todo : this would be nice to have but we do not always know it, especially in HBM case.
// private SimpleAttributeBinding otherSide;
// private SimpleSingularAttributeBinding otherSide;
public CollectionKey(PluralAttributeBinding collection) {
public CollectionKey(AbstractPluralAttributeBinding collection) {
this.collection = collection;
}
}

View File

@ -27,7 +27,7 @@ package org.hibernate.metamodel.binding;
* @author Gail Badner
*/
public class CompositeCollectionElement extends CollectionElement {
public CompositeCollectionElement(PluralAttributeBinding binding) {
super( binding, CollectionElementType.COMPOSITE );
public CompositeCollectionElement(AbstractPluralAttributeBinding binding) {
super( binding, CollectionElementNature.COMPOSITE );
}
}

View File

@ -28,14 +28,13 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.persister.entity.EntityPersister;
@ -65,7 +64,7 @@ public class EntityBinding {
private final EntityIdentifier entityIdentifier = new EntityIdentifier( this );
private EntityDiscriminator entityDiscriminator;
private SimpleAttributeBinding versionBinding;
private SimpleSingularAttributeBinding versionBinding;
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
@ -115,6 +114,11 @@ public class EntityBinding {
this.baseTable = baseTable;
}
public TableSpecification getTable(String containingTableName) {
// todo : implement this for secondary table look ups. for now we just return the base table
return baseTable;
}
public boolean isRoot() {
return superEntityBinding == null;
}
@ -147,11 +151,11 @@ public class EntityBinding {
return versionBinding != null;
}
public void setVersionBinding(SimpleAttributeBinding versionBinding) {
public void setVersionBinding(SimpleSingularAttributeBinding versionBinding) {
this.versionBinding = versionBinding;
}
public SimpleAttributeBinding getVersioningValueBinding() {
public SimpleSingularAttributeBinding getVersioningValueBinding() {
return versionBinding;
}
@ -201,47 +205,44 @@ public class EntityBinding {
return entityReferencingAttributeBindings;
}
public SimpleAttributeBinding makeSimpleIdAttributeBinding(Attribute attribute) {
final SimpleAttributeBinding binding = makeSimpleAttributeBinding( attribute, true, true );
public SimpleSingularAttributeBinding makeSimpleIdAttributeBinding(SingularAttribute attribute) {
final SimpleSingularAttributeBinding binding = makeSimpleAttributeBinding( attribute, true, true );
getEntityIdentifier().setValueBinding( binding );
return binding;
}
//
// public EntityDiscriminator makeEntityDiscriminator(Attribute attribute) {
// if ( entityDiscriminator != null ) {
// throw new AssertionFailure( "Creation of entity discriminator was called more than once" );
// }
// entityDiscriminator = new EntityDiscriminator();
// entityDiscriminator.setValueBinding( makeSimpleAttributeBinding( attribute, true, false ) );
// return entityDiscriminator;
// }
public EntityDiscriminator makeEntityDiscriminator(Attribute attribute) {
if ( entityDiscriminator != null ) {
throw new AssertionFailure( "Creation of entity discriminator was called more than once" );
}
entityDiscriminator = new EntityDiscriminator();
entityDiscriminator.setValueBinding( makeSimpleAttributeBinding( attribute, true, false ) );
return entityDiscriminator;
}
public SimpleAttributeBinding makeVersionBinding(Attribute attribute) {
public SimpleSingularAttributeBinding makeVersionBinding(SingularAttribute attribute) {
versionBinding = makeSimpleAttributeBinding( attribute, true, false );
return versionBinding;
}
public SimpleAttributeBinding makeSimpleAttributeBinding(Attribute attribute) {
public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute) {
return makeSimpleAttributeBinding( attribute, false, false );
}
private SimpleAttributeBinding makeSimpleAttributeBinding(Attribute attribute, boolean forceNonNullable, boolean forceUnique) {
final SimpleAttributeBinding binding = new SimpleAttributeBinding( this, forceNonNullable, forceUnique );
binding.setAttribute( attribute );
private SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute, boolean forceNonNullable, boolean forceUnique) {
final SimpleSingularAttributeBinding binding = new SimpleSingularAttributeBinding( this, attribute, forceNonNullable, forceUnique );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(Attribute attribute) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this );
binding.setAttribute( attribute );
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementType collectionElementType) {
final BagBinding binding = new BagBinding( this, collectionElementType );
binding.setAttribute( attribute );
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature) {
final BagBinding binding = new BagBinding( this, attribute, nature );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}

View File

@ -32,7 +32,7 @@ import org.hibernate.metamodel.relational.state.ValueRelationalState;
* @author Steve Ebersole
*/
public class EntityDiscriminator {
private SimpleAttributeBinding valueBinding;
private SimpleSingularAttributeBinding valueBinding;
private String discriminatorValue;
private boolean forced;
private boolean inserted = true;
@ -40,12 +40,12 @@ public class EntityDiscriminator {
public EntityDiscriminator() {
}
public SimpleAttributeBinding getValueBinding() {
public SimpleSingularAttributeBinding getValueBinding() {
return valueBinding;
}
/* package-protected */
void setValueBinding(SimpleAttributeBinding valueBinding) {
void setValueBinding(SimpleSingularAttributeBinding valueBinding) {
this.valueBinding = valueBinding;
}
@ -60,11 +60,6 @@ public class EntityDiscriminator {
return this;
}
public EntityDiscriminator initialize(ValueRelationalState state) {
valueBinding.initialize( state );
return this;
}
public String getDiscriminatorValue() {
return discriminatorValue;
}

View File

@ -44,7 +44,7 @@ public class EntityIdentifier {
);
private final EntityBinding entityBinding;
private SimpleAttributeBinding attributeBinding;
private SimpleSingularAttributeBinding attributeBinding;
private IdentifierGenerator identifierGenerator;
private IdGenerator idGenerator;
private boolean isIdentifierMapper = false;
@ -59,11 +59,11 @@ public class EntityIdentifier {
this.entityBinding = entityBinding;
}
public SimpleAttributeBinding getValueBinding() {
public SimpleSingularAttributeBinding getValueBinding() {
return attributeBinding;
}
public void setValueBinding(SimpleAttributeBinding attributeBinding) {
public void setValueBinding(SimpleSingularAttributeBinding attributeBinding) {
if ( this.attributeBinding != null ) {
// todo : error? or just log? For now throw exception and see what happens. Easier to see whether this
// method gets called multiple times
@ -77,7 +77,7 @@ public class EntityIdentifier {
}
public boolean isEmbedded() {
return attributeBinding.getValuesSpan()>1;
return attributeBinding.getSimpleValueSpan()>1;
}
public boolean isIdentifierMapper() {

View File

@ -32,6 +32,4 @@ public interface KeyValueBinding extends AttributeBinding {
public boolean isKeyCascadeDeleteEnabled();
public String getUnsavedValue();
public boolean isUpdatable();
}

View File

@ -23,15 +23,11 @@
*/
package org.hibernate.metamodel.binding;
import java.util.HashMap;
import org.dom4j.Element;
/**
* @author Gail Badner
*/
public class ManyToAnyCollectionElement extends CollectionElement {
ManyToAnyCollectionElement(PluralAttributeBinding binding) {
super( binding, CollectionElementType.MANY_TO_ANY );
ManyToAnyCollectionElement(AbstractPluralAttributeBinding binding) {
super( binding, CollectionElementNature.MANY_TO_ANY );
}
}

View File

@ -31,13 +31,14 @@ import org.dom4j.Element;
* @author Gail Badner
*/
public class ManyToManyCollectionElement extends CollectionElement {
private final java.util.Map manyToManyFilters = new HashMap();
private String manyToManyWhere;
private String manyToManyOrderBy;
ManyToManyCollectionElement(PluralAttributeBinding binding) {
super( binding, CollectionElementType.MANY_TO_MANY );
ManyToManyCollectionElement(AbstractPluralAttributeBinding binding) {
super( binding, CollectionElementNature.MANY_TO_MANY );
}
public void fromHbmXml(Element node){

View File

@ -23,15 +23,12 @@
*/
package org.hibernate.metamodel.binding;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.MappingException;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.metamodel.binding.state.ManyToOneAttributeBindingState;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.ForeignKey;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.state.ManyToOneRelationalState;
import org.hibernate.metamodel.domain.SingularAttribute;
/**
* TODO : javadoc
@ -39,33 +36,24 @@ import org.hibernate.metamodel.relational.state.ManyToOneRelationalState;
* @author Gail Badner
* @author Steve Ebersole
*/
public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements SingularAssociationAttributeBinding {
private String referencedAttributeName;
public class ManyToOneAttributeBinding extends SimpleSingularAttributeBinding implements SingularAssociationAttributeBinding {
private String referencedEntityName;
private String referencedAttributeName;
private AttributeBinding referencedAttributeBinding;
private boolean isLogicalOneToOne;
private String foreignKeyName;
private AttributeBinding referencedAttributeBinding;
private CascadeStyle cascadeStyle;
private FetchMode fetchMode;
private Iterable<CascadeStyle> cascadeStyles;
ManyToOneAttributeBinding(EntityBinding entityBinding) {
super( entityBinding, false, false );
ManyToOneAttributeBinding(EntityBinding entityBinding, SingularAttribute attribute) {
super( entityBinding, attribute, false, false );
}
public final ManyToOneAttributeBinding initialize(ManyToOneAttributeBindingState state) {
super.initialize( state );
referencedAttributeName = state.getReferencedAttributeName();
referencedEntityName = state.getReferencedEntityName();
return this;
}
public final ManyToOneAttributeBinding initialize(ManyToOneRelationalState state) {
super.initializeValueRelationalState( state );
isLogicalOneToOne = state.isLogicalOneToOne();
foreignKeyName = state.getForeignKeyName();
return this;
@Override
public boolean isAssociation() {
return true;
}
@Override
@ -94,13 +82,39 @@ public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements
}
@Override
public Iterable<CascadeStyle> getCascadeStyles() {
return cascadeStyles;
public CascadeStyle getCascadeStyle() {
return cascadeStyle;
}
@Override
public void setCascadeStyles(Iterable<CascadeStyle> cascadeStyles) {
this.cascadeStyles = cascadeStyles;
List<CascadeStyle> cascadeStyleList = new ArrayList<CascadeStyle>();
for ( CascadeStyle style : cascadeStyles ) {
if ( style != CascadeStyle.NONE ) {
cascadeStyleList.add( style );
}
}
if ( cascadeStyleList.isEmpty() ) {
cascadeStyle = CascadeStyle.NONE;
}
else if ( cascadeStyleList.size() == 1 ) {
cascadeStyle = cascadeStyleList.get( 0 );
}
else {
cascadeStyle = new CascadeStyle.MultipleCascadeStyle(
cascadeStyleList.toArray( new CascadeStyle[ cascadeStyleList.size() ] )
);
}
}
@Override
public FetchMode getFetchMode() {
return fetchMode;
}
@Override
public void setFetchMode(FetchMode fetchMode) {
this.fetchMode = fetchMode;
}
@Override
@ -127,7 +141,7 @@ public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements
);
}
this.referencedAttributeBinding = referencedAttributeBinding;
buildForeignKey();
// buildForeignKey();
}
@Override
@ -143,52 +157,47 @@ public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements
return referencedAttributeBinding.getEntityBinding();
}
private void buildForeignKey() {
// TODO: move this stuff to relational model
ForeignKey foreignKey = getValue().getTable()
.createForeignKey( referencedAttributeBinding.getValue().getTable(), foreignKeyName );
Iterator<SimpleValue> referencingValueIterator = getValues().iterator();
Iterator<SimpleValue> targetValueIterator = referencedAttributeBinding.getValues().iterator();
while ( referencingValueIterator.hasNext() ) {
if ( !targetValueIterator.hasNext() ) {
// TODO: improve this message
throw new MappingException(
"number of values in many-to-one reference is greater than number of values in target"
);
}
SimpleValue referencingValue = referencingValueIterator.next();
SimpleValue targetValue = targetValueIterator.next();
if ( Column.class.isInstance( referencingValue ) ) {
if ( !Column.class.isInstance( targetValue ) ) {
// TODO improve this message
throw new MappingException( "referencing value is a column, but target is not a column" );
}
foreignKey.addColumnMapping( Column.class.cast( referencingValue ), Column.class.cast( targetValue ) );
}
else if ( Column.class.isInstance( targetValue ) ) {
// TODO: improve this message
throw new MappingException( "referencing value is not a column, but target is a column." );
}
}
if ( targetValueIterator.hasNext() ) {
throw new MappingException( "target value has more simple values than referencing value" );
}
}
public boolean isSimpleValue() {
return false;
}
public void validate() {
// can't check this until both the domain and relational states are initialized...
if ( getCascadeTypes().contains( CascadeType.DELETE_ORPHAN ) ) {
if ( !isLogicalOneToOne ) {
throw new MappingException(
"many-to-one attribute [" + getAttribute().getName() + "] does not support orphan delete as it is not unique"
);
}
}
//TODO: validate that the entity reference is resolved
}
// private void buildForeignKey() {
// // TODO: move this stuff to relational model
// ForeignKey foreignKey = getValue().getTable()
// .createForeignKey( referencedAttributeBinding.getValue().getTable(), foreignKeyName );
// Iterator<SimpleValue> referencingValueIterator = getSimpleValues().iterator();
// Iterator<SimpleValue> targetValueIterator = referencedAttributeBinding.getSimpleValues().iterator();
// while ( referencingValueIterator.hasNext() ) {
// if ( !targetValueIterator.hasNext() ) {
// // TODO: improve this message
// throw new MappingException(
// "number of values in many-to-one reference is greater than number of values in target"
// );
// }
// SimpleValue referencingValue = referencingValueIterator.next();
// SimpleValue targetValue = targetValueIterator.next();
// if ( Column.class.isInstance( referencingValue ) ) {
// if ( !Column.class.isInstance( targetValue ) ) {
// // TODO improve this message
// throw new MappingException( "referencing value is a column, but target is not a column" );
// }
// foreignKey.addColumnMapping( Column.class.cast( referencingValue ), Column.class.cast( targetValue ) );
// }
// else if ( Column.class.isInstance( targetValue ) ) {
// // TODO: improve this message
// throw new MappingException( "referencing value is not a column, but target is a column." );
// }
// }
// if ( targetValueIterator.hasNext() ) {
// throw new MappingException( "target value has more simple values than referencing value" );
// }
// }
//
// public void validate() {
// // can't check this until both the domain and relational states are initialized...
// if ( getCascadeTypes().contains( CascadeType.DELETE_ORPHAN ) ) {
// if ( !isLogicalOneToOne ) {
// throw new MappingException(
// "many-to-one attribute [" + getAttribute().getName() + "] does not support orphan delete as it is not unique"
// );
// }
// }
// //TODO: validate that the entity reference is resolved
// }
}

View File

@ -28,7 +28,7 @@ package org.hibernate.metamodel.binding;
*/
public class OneToManyCollectionElement extends CollectionElement {
OneToManyCollectionElement(PluralAttributeBinding binding) {
super( binding, CollectionElementType.ONE_TO_MANY );
OneToManyCollectionElement(AbstractPluralAttributeBinding binding) {
super( binding, CollectionElementNature.ONE_TO_MANY );
}
}

View File

@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* Copyright (c) 2011, Red Hat Inc. 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 Inc.
@ -23,219 +23,18 @@
*/
package org.hibernate.metamodel.binding;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import org.jboss.logging.Logger;
import org.hibernate.FetchMode;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.binding.state.PluralAttributeBindingState;
import org.hibernate.metamodel.relational.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public abstract class PluralAttributeBinding extends AbstractAttributeBinding {
public interface PluralAttributeBinding extends AttributeBinding, AssociationAttributeBinding {
// todo : really it is the element (and/or index) that can be associative not the collection itself...
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class, PluralAttributeBinding.class.getName()
);
public CollectionKey getCollectionKey();
private Table collectionTable;
public CollectionElement getCollectionElement();
private CollectionKey collectionKey;
private final CollectionElement collectionElement;
public Table getCollectionTable();
// private String role;
private FetchMode fetchMode;
private boolean extraLazy;
private boolean inverse;
private boolean mutable = true;
private boolean subselectLoadable;
private String cacheConcurrencyStrategy;
private String cacheRegionName;
private String orderBy;
private String where;
private String referencedPropertyName;
private boolean sorted;
private Comparator comparator;
private String comparatorClassName;
private boolean orphanDelete;
private int batchSize = -1;
private boolean embedded = true;
private boolean optimisticLocked = true;
private Class collectionPersisterClass;
private final java.util.Map filters = new HashMap();
private final java.util.Set<String> synchronizedTables = new HashSet<String>();
private CustomSQL customSQLInsert;
private CustomSQL customSQLUpdate;
private CustomSQL customSQLDelete;
private CustomSQL customSQLDeleteAll;
private String loaderName;
protected PluralAttributeBinding(EntityBinding entityBinding, CollectionElementType collectionElementType) {
super( entityBinding );
collectionElement = collectionElementType.createCollectionElement( this );
}
protected void initializeBinding(PluralAttributeBindingState state) {
super.initialize( state );
fetchMode = state.getFetchMode();
extraLazy = state.isExtraLazy();
collectionElement.setNodeName( state.getElementNodeName() );
collectionElement.setTypeName( state.getElementTypeName() );
inverse = state.isInverse();
mutable = state.isMutable();
subselectLoadable = state.isSubselectLoadable();
if ( isSubselectLoadable() ) {
getEntityBinding().setSubselectLoadableCollections( true );
}
cacheConcurrencyStrategy = state.getCacheConcurrencyStrategy();
cacheRegionName = state.getCacheRegionName();
orderBy = state.getOrderBy();
where = state.getWhere();
referencedPropertyName = state.getReferencedPropertyName();
sorted = state.isSorted();
comparator = state.getComparator();
comparatorClassName = state.getComparatorClassName();
orphanDelete = state.isOrphanDelete();
batchSize = state.getBatchSize();
embedded = state.isEmbedded();
optimisticLocked = state.isOptimisticLocked();
collectionPersisterClass = state.getCollectionPersisterClass();
filters.putAll( state.getFilters() );
synchronizedTables.addAll( state.getSynchronizedTables() );
customSQLInsert = state.getCustomSQLInsert();
customSQLUpdate = state.getCustomSQLUpdate();
customSQLDelete = state.getCustomSQLDelete();
customSQLDeleteAll = state.getCustomSQLDeleteAll();
loaderName = state.getLoaderName();
}
@Override
public boolean isSimpleValue() {
return false;
}
public Table getCollectionTable() {
return collectionTable;
}
public void setCollectionTable(Table collectionTable) {
this.collectionTable = collectionTable;
}
public CollectionKey getCollectionKey() {
return collectionKey;
}
public void setCollectionKey(CollectionKey collectionKey) {
this.collectionKey = collectionKey;
}
public CollectionElement getCollectionElement() {
return collectionElement;
}
public boolean isExtraLazy() {
return extraLazy;
}
public boolean isInverse() {
return inverse;
}
public boolean isMutable() {
return mutable;
}
public boolean isSubselectLoadable() {
return subselectLoadable;
}
public String getCacheConcurrencyStrategy() {
return cacheConcurrencyStrategy;
}
public String getCacheRegionName() {
return cacheRegionName;
}
public String getOrderBy() {
return orderBy;
}
public String getWhere() {
return where;
}
public String getReferencedPropertyName() {
return referencedPropertyName;
}
public boolean isSorted() {
return sorted;
}
public Comparator getComparator() {
return comparator;
}
public void setComparator(Comparator comparator) {
this.comparator = comparator;
}
public String getComparatorClassName() {
return comparatorClassName;
}
public boolean isOrphanDelete() {
return orphanDelete;
}
public int getBatchSize() {
return batchSize;
}
public boolean isOptimisticLocked() {
return optimisticLocked;
}
public Class getCollectionPersisterClass() {
return collectionPersisterClass;
}
public void addFilter(String name, String condition) {
filters.put( name, condition );
}
public java.util.Map getFilterMap() {
return filters;
}
public CustomSQL getCustomSQLInsert() {
return customSQLInsert;
}
public CustomSQL getCustomSQLUpdate() {
return customSQLUpdate;
}
public CustomSQL getCustomSQLDelete() {
return customSQLDelete;
}
public CustomSQL getCustomSQLDeleteAll() {
return customSQLDeleteAll;
}
public String getLoaderName() {
return loaderName;
}
}

View File

@ -31,81 +31,68 @@ import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.state.ColumnRelationalState;
import org.hibernate.metamodel.relational.state.ValueRelationalState;
import org.hibernate.metamodel.source.MetaAttributeContext;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class SimpleAttributeBinding extends AbstractAttributeBinding implements SingularAttributeBinding, KeyValueBinding {
private boolean insertable;
private boolean updatable;
private PropertyGeneration generation;
public class SimpleSingularAttributeBinding
extends AbstractSingularAttributeBinding
implements SingularAttributeBinding, KeyValueBinding {
private String propertyAccessorName;
private String unsavedValue;
private PropertyGeneration generation;
private boolean includedInOptimisticLocking;
private boolean forceNonNullable;
private boolean forceUnique;
private boolean keyCascadeDeleteEnabled;
private boolean includedInOptimisticLocking;
private MetaAttributeContext metaAttributeContext;
SimpleAttributeBinding(EntityBinding entityBinding, boolean forceNonNullable, boolean forceUnique) {
super( entityBinding );
SimpleSingularAttributeBinding(
EntityBinding entityBinding,
SingularAttribute attribute,
boolean forceNonNullable,
boolean forceUnique) {
super( entityBinding, attribute );
this.forceNonNullable = forceNonNullable;
this.forceUnique = forceUnique;
}
public final SimpleAttributeBinding initialize(SimpleAttributeBindingState state) {
super.initialize( state );
insertable = state.isInsertable();
updatable = state.isUpdatable();
keyCascadeDeleteEnabled = state.isKeyCascadeDeleteEnabled();
unsavedValue = state.getUnsavedValue();
generation = state.getPropertyGeneration() == null ? PropertyGeneration.NEVER : state.getPropertyGeneration();
return this;
}
public SimpleAttributeBinding initialize(ValueRelationalState state) {
super.initializeValueRelationalState( state );
return this;
}
private boolean isUnique(ColumnRelationalState state) {
return isPrimaryKey() || state.isUnique();
@Override
public boolean isAssociation() {
return false;
}
@Override
public SingularAttribute getAttribute() {
return (SingularAttribute) super.getAttribute();
public String getUnsavedValue() {
return unsavedValue;
}
public void setUnsavedValue(String unsavedValue) {
this.unsavedValue = unsavedValue;
}
@Override
public boolean isSimpleValue() {
return true;
public PropertyGeneration getGeneration() {
return generation;
}
public boolean isInsertable() {
return insertable;
public void setGeneration(PropertyGeneration generation) {
this.generation = generation;
}
public void setInsertable(boolean insertable) {
this.insertable = insertable;
public boolean isIncludedInOptimisticLocking() {
return includedInOptimisticLocking;
}
public boolean isUpdatable() {
return updatable;
}
public void setUpdatable(boolean updatable) {
this.updatable = updatable;
public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking) {
this.includedInOptimisticLocking = includedInOptimisticLocking;
}
@Override
@ -117,15 +104,6 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
this.keyCascadeDeleteEnabled = keyCascadeDeleteEnabled;
}
@Override
public String getUnsavedValue() {
return unsavedValue;
}
public void setUnsavedValue(String unsaveValue) {
this.unsavedValue = unsaveValue;
}
public boolean forceNonNullable() {
return forceNonNullable;
}
@ -134,30 +112,6 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
return forceUnique;
}
public PropertyGeneration getGeneration() {
return generation;
}
public void setGeneration(PropertyGeneration generation) {
this.generation = generation;
}
public String getPropertyAccessorName() {
return propertyAccessorName;
}
public void setPropertyAccessorName(String propertyAccessorName) {
this.propertyAccessorName = propertyAccessorName;
}
public boolean isIncludedInOptimisticLocking() {
return includedInOptimisticLocking;
}
public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking) {
this.includedInOptimisticLocking = includedInOptimisticLocking;
}
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}

View File

@ -0,0 +1,100 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc.
*
* 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.metamodel.binding;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.DerivedValue;
import org.hibernate.metamodel.relational.SimpleValue;
/**
* @author Steve Ebersole
*/
public class SimpleValueBinding {
private SimpleValue simpleValue;
private boolean includeInInsert;
private boolean includeInUpdate;
public SimpleValueBinding() {
this( true, true );
}
public SimpleValueBinding(SimpleValue simpleValue) {
this();
setSimpleValue( simpleValue );
}
public SimpleValueBinding(SimpleValue simpleValue, boolean includeInInsert, boolean includeInUpdate) {
this( includeInInsert, includeInUpdate );
setSimpleValue( simpleValue );
}
public SimpleValueBinding(boolean includeInInsert, boolean includeInUpdate) {
this.includeInInsert = includeInInsert;
this.includeInUpdate = includeInUpdate;
}
public SimpleValue getSimpleValue() {
return simpleValue;
}
public void setSimpleValue(SimpleValue simpleValue) {
this.simpleValue = simpleValue;
if ( DerivedValue.class.isInstance( simpleValue ) ) {
includeInInsert = false;
includeInUpdate = false;
}
}
public boolean isDerived() {
return DerivedValue.class.isInstance( simpleValue );
}
public boolean isNullable() {
return isDerived() || Column.class.cast( simpleValue ).isNullable();
}
/**
* Is the value to be inserted as part of its binding here?
* <p/>
* <b>NOTE</b> that a column may be bound to multiple attributes. The purpose of this value is to track this
* notion of "insertability" for this particular binding.
*
* @return {@code true} indicates the value should be included; {@code false} indicates it should not
*/
public boolean isIncludeInInsert() {
return includeInInsert;
}
public void setIncludeInInsert(boolean includeInInsert) {
this.includeInInsert = includeInInsert;
}
public boolean isIncludeInUpdate() {
return includeInUpdate;
}
public void setIncludeInUpdate(boolean includeInUpdate) {
this.includeInUpdate = includeInUpdate;
}
}

View File

@ -23,8 +23,59 @@
*/
package org.hibernate.metamodel.binding;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.relational.Value;
/**
* Specialized binding contract for singular (non-collection) attributes
*
* @author Steve Ebersole
*/
public interface SingularAttributeBinding extends AttributeBinding {
/**
* Obtain the value bound here. This could potentially be a {@link org.hibernate.metamodel.relational.Tuple}
* indicating multiple database values are bound, in which case access to the individual values can be achieved by
* either casting this return to {@link org.hibernate.metamodel.relational.Tuple} and using its
* {@link org.hibernate.metamodel.relational.Tuple#values()} method or using the {@link #getSimpleValueBindings()}
* method here and accessing each bindings {@link SimpleValueBinding#getSimpleValue simple value}
*
* @return The bound value
*/
public Value getValue();
/**
* Returns the number of {@link SimpleValueBinding} objects that will be returned by
* {@link #getSimpleValueBindings()}
*
* @return the number of {@link SimpleValueBinding simple value bindings}
*
* @see #getSimpleValueBindings()
*/
public int getSimpleValueSpan();
public Iterable<SimpleValueBinding> getSimpleValueBindings();
public void setSimpleValueBindings(Iterable<SimpleValueBinding> simpleValueBindings);
/**
* Convenience method to determine if any {@link SimpleValueBinding simple value bindings} are derived values
* (formula mappings).
*
* @return {@code true} indicates that the binding contains a derived value; {@code false} indicates it does not.
*/
public boolean hasDerivedValue();
/**
* Convenience method to determine if all {@link SimpleValueBinding simple value bindings} allow nulls.
*
* @return {@code true} indicates that all values allow {@code null}; {@code false} indicates one or more do not
*/
public boolean isNullable();
/**
* Obtain the generation strategy for this attribute/value.
*
* @return The generation strategy
*/
public PropertyGeneration getGeneration();
}

View File

@ -29,12 +29,11 @@ import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.relational.AuxiliaryDatabaseObject;
import org.hibernate.metamodel.relational.Database;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.type.TypeResolver;
@ -53,7 +52,7 @@ public interface MetadataImplementor extends Metadata, BindingContext, Mapping {
public void addEntity(EntityBinding entityBinding);
public void addCollection(PluralAttributeBinding collectionBinding);
public void addCollection(AbstractPluralAttributeBinding collectionBinding);
public void addFetchProfile(FetchProfile profile);

View File

@ -102,6 +102,21 @@ public class ColumnSourceImpl implements ColumnSource {
// todo
return null;
}
@Override
public boolean isIncludedInInsert() {
return columnValues.isInsertable();
}
@Override
public boolean isIncludedInUpdate() {
return columnValues.isUpdatable();
}
@Override
public String getContainingTableName() {
return columnValues.getTable();
}
}

View File

@ -47,7 +47,7 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
@Override
public boolean isVirtualAttribute() {
return false; //To change body of implemented methods use File | Settings | File Templates.
return false;
}
@Override
@ -72,7 +72,8 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
@Override
public String getPropertyAccessorName() {
return null; //To change body of implemented methods use File | Settings | File Templates.
// todo : implememt
return null;
}
@Override
@ -115,6 +116,21 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
return Collections.emptySet();
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return true;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
List<RelationalValueSource> valueSources = new ArrayList<RelationalValueSource>();

View File

@ -1,7 +1,32 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc.
*
* 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.metamodel.source.annotations.attribute;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.binder.ToOneAttributeSource;
@ -11,10 +36,15 @@ import org.hibernate.metamodel.source.binder.ToOneAttributeSource;
*/
public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implements ToOneAttributeSource {
private final AssociationAttribute associationAttribute;
private final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>();
public ToOneAttributeSourceImpl(AssociationAttribute associationAttribute) {
super( associationAttribute );
this.associationAttribute = associationAttribute;
for ( javax.persistence.CascadeType cascadeType : associationAttribute.getCascadeTypes() ) {
// todo : ...
}
}
@Override
@ -33,8 +63,14 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem
}
@Override
public Iterable<CascadeStyle> getCascadeStyle() {
return Collections.emptySet();
public Iterable<CascadeStyle> getCascadeStyles() {
return cascadeStyles;
}
@Override
public FetchMode getFetchMode() {
// todo : implement
return FetchMode.DEFAULT;
}
}

View File

@ -632,5 +632,11 @@ public class EntityClass extends ConfiguredClass {
public String getExplicitTableName() {
return tableName;
}
@Override
public String getLogicalName() {
// todo : (steve) hardy, not sure what to use here... null is ok for the primary table name. this is part of the secondary table support.
return null;
}
}
}

View File

@ -23,6 +23,7 @@
*/
package org.hibernate.metamodel.source.binder;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle;
/**
@ -37,4 +38,11 @@ public interface AssociationAttributeSource extends AttributeSource {
* @return The cascade styles.
*/
public Iterable<CascadeStyle> getCascadeStyles();
/**
* Obtain the fetch mode to be applied to this association.
*
* @return The fetch mode.
*/
public FetchMode getFetchMode();
}

View File

@ -43,10 +43,15 @@ public interface AttributeSource {
*/
public boolean isSingular();
public String getPropertyAccessorName();
public boolean isIncludedInOptimisticLocking();
/**
* Obtain the meta-attribute sources associated with this attribute.
*
* @return The meta-attribute sources.
*/
public Iterable<MetaAttributeSource> metaAttributes();
}

View File

@ -34,14 +34,20 @@ import org.hibernate.EntityMode;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.beans.BeanInfoHelper;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.CollectionElementNature;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.binding.ManyToOneAttributeBinding;
import org.hibernate.metamodel.binding.MetaAttribute;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.binding.SimpleSingularAttributeBinding;
import org.hibernate.metamodel.binding.SimpleValueBinding;
import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Identifier;
@ -278,19 +284,6 @@ public class Binder {
// Attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void bindAttributes(AttributeSourceContainer attributeSourceContainer, EntityBinding entityBinding) {
// todo : we really need the notion of a Stack here for the table from which the columns come for binding these attributes.
// todo : adding the concept (interface) of a source of attribute metadata would allow reuse of this method for entity, component, unique-key, etc
// for now, simply assume all columns come from the base table....
for ( AttributeSource attributeSource : attributeSourceContainer.attributeSources() ) {
if ( attributeSource.isSingular() ) {
doBasicSingularAttributeBindingCreation( (SingularAttributeSource) attributeSource, entityBinding );
}
// todo : components and collections
}
}
private void bindIdentifier(RootEntitySource entitySource, EntityBinding entityBinding) {
if ( entitySource.getIdentifierSource() == null ) {
throw new AssertionFailure( "Expecting identifier information on root entity descriptor" );
@ -311,7 +304,7 @@ public class Binder {
}
private void bindSimpleIdentifier(SimpleIdentifierSource identifierSource, EntityBinding entityBinding) {
final SimpleAttributeBinding idAttributeBinding = doBasicSingularAttributeBindingCreation(
final SimpleSingularAttributeBinding idAttributeBinding = doBasicSingularAttributeBindingCreation(
identifierSource.getIdentifierAttributeSource(), entityBinding
);
@ -342,7 +335,7 @@ public class Binder {
return;
}
SimpleAttributeBinding attributeBinding = doBasicSingularAttributeBindingCreation(
SimpleSingularAttributeBinding attributeBinding = doBasicSingularAttributeBindingCreation(
versioningAttributeSource, entityBinding
);
entityBinding.setVersionBinding( attributeBinding );
@ -356,14 +349,58 @@ public class Binder {
// todo : implement
}
private SimpleAttributeBinding doBasicSingularAttributeBindingCreation(
private void bindAttributes(AttributeSourceContainer attributeSourceContainer, EntityBinding entityBinding) {
// todo : we really need the notion of a Stack here for the table from which the columns come for binding these attributes.
// todo : adding the concept (interface) of a source of attribute metadata would allow reuse of this method for entity, component, unique-key, etc
// for now, simply assume all columns come from the base table....
for ( AttributeSource attributeSource : attributeSourceContainer.attributeSources() ) {
if ( attributeSource.isSingular() ) {
final SingularAttributeSource singularAttributeSource = (SingularAttributeSource) attributeSource;
if ( singularAttributeSource.getNature() == SingularAttributeNature.COMPONENT ) {
throw new NotYetImplementedException( "Component binding not yet implemented :(" );
}
else {
doBasicSingularAttributeBindingCreation( singularAttributeSource, entityBinding );
}
}
else {
bindPersistentCollection( (PluralAttributeSource) attributeSource, entityBinding );
}
}
}
private void bindPersistentCollection(PluralAttributeSource attributeSource, EntityBinding entityBinding) {
final AbstractPluralAttributeBinding pluralAttributeBinding;
if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) {
final PluralAttribute pluralAttribute = entityBinding.getEntity().locateOrCreateBag( attributeSource.getName() );
pluralAttributeBinding = entityBinding.makeBagAttributeBinding( pluralAttribute, convert( attributeSource.getPluralAttributeElementNature() ) );
}
else {
// todo : implement other collection types
throw new NotYetImplementedException( "Collections other than bag not yet implmented :(" );
}
doBasicAttributeBinding( attributeSource, pluralAttributeBinding );
}
private void doBasicAttributeBinding(AttributeSource attributeSource, AttributeBinding attributeBinding) {
attributeBinding.setPropertyAccessorName( attributeSource.getPropertyAccessorName() );
attributeBinding.setIncludedInOptimisticLocking( attributeSource.isIncludedInOptimisticLocking() );
}
private CollectionElementNature convert(PluralAttributeElementNature pluralAttributeElementNature) {
return CollectionElementNature.valueOf( pluralAttributeElementNature.name() );
}
private SimpleSingularAttributeBinding doBasicSingularAttributeBindingCreation(
SingularAttributeSource attributeSource,
EntityBinding entityBinding) {
final SingularAttribute attribute = attributeSource.isVirtualAttribute()
? entityBinding.getEntity().locateOrCreateVirtualAttribute( attributeSource.getName() )
: entityBinding.getEntity().locateOrCreateSingularAttribute( attributeSource.getName() );
final SimpleAttributeBinding attributeBinding;
final SimpleSingularAttributeBinding attributeBinding;
if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) {
attributeBinding = entityBinding.makeSimpleAttributeBinding( attribute );
resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding );
@ -377,8 +414,6 @@ public class Binder {
throw new NotYetImplementedException();
}
attributeBinding.setInsertable( attributeSource.isInsertable() );
attributeBinding.setUpdatable( attributeSource.isUpdatable() );
attributeBinding.setGeneration( attributeSource.getGeneration() );
attributeBinding.setLazy( attributeSource.isLazy() );
attributeBinding.setIncludedInOptimisticLocking( attributeSource.isIncludedInOptimisticLocking() );
@ -391,8 +426,7 @@ public class Binder {
)
);
final org.hibernate.metamodel.relational.Value relationalValue = makeValue( attributeSource, attributeBinding );
attributeBinding.setValue( relationalValue );
bindRelationalValues( attributeSource, attributeBinding );
attributeBinding.setMetaAttributeContext(
buildMetaAttributeContext( attributeSource.metaAttributes(), entityBinding.getMetaAttributeContext() )
@ -401,7 +435,7 @@ public class Binder {
return attributeBinding;
}
private void resolveTypeInformation(ExplicitHibernateTypeSource typeSource, SimpleAttributeBinding attributeBinding) {
private void resolveTypeInformation(ExplicitHibernateTypeSource typeSource, SimpleSingularAttributeBinding attributeBinding) {
final Class<?> attributeJavaType = determineJavaType( attributeBinding.getAttribute() );
if ( attributeJavaType != null ) {
attributeBinding.getHibernateTypeDescriptor().setJavaTypeName( attributeJavaType.getName() );
@ -472,6 +506,7 @@ public class Binder {
attributeBinding.setReferencedAttributeName( attributeSource.getReferencedEntityAttributeName() );
attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() );
attributeBinding.setFetchMode( attributeSource.getFetchMode() );
}
private MetaAttributeContext buildMetaAttributeContext(EntitySource entitySource) {
@ -556,18 +591,17 @@ public class Binder {
// todo : implement
}
private org.hibernate.metamodel.relational.Value makeValue(
private void bindRelationalValues(
RelationalValueSourceContainer relationalValueSourceContainer,
SimpleAttributeBinding attributeBinding) {
SingularAttributeBinding attributeBinding) {
// todo : to be completely correct, we need to know which table the value belongs to.
// There is a note about this somewhere else with ideas on the subject.
// For now, just use the entity's base table.
final TableSpecification table = attributeBinding.getEntityBinding().getBaseTable();
List<SimpleValueBinding> valueBindings = new ArrayList<SimpleValueBinding>();
if ( relationalValueSourceContainer.relationalValueSources().size() > 0 ) {
List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( RelationalValueSource valueSource : relationalValueSourceContainer.relationalValueSources() ) {
final TableSpecification table = attributeBinding.getEntityBinding()
.getTable( valueSource.getContainingTableName() );
if ( ColumnSource.class.isInstance( valueSource ) ) {
final ColumnSource columnSource = ColumnSource.class.cast( valueSource );
final Column column = table.locateOrCreateColumn( columnSource.getName() );
@ -581,28 +615,35 @@ public class Binder {
column.setUnique( columnSource.isUnique() );
column.setCheckCondition( columnSource.getCheckCondition() );
column.setComment( columnSource.getComment() );
values.add( column );
valueBindings.add(
new SimpleValueBinding(
column,
columnSource.isIncludedInInsert(),
columnSource.isIncludedInUpdate()
)
);
}
else {
values.add( table.locateOrCreateDerivedValue( ( (DerivedValueSource) valueSource ).getExpression() ) );
valueBindings.add(
new SimpleValueBinding(
table.locateOrCreateDerivedValue( ( (DerivedValueSource) valueSource ).getExpression() )
)
);
}
}
if ( values.size() == 1 ) {
return values.get( 0 );
}
Tuple tuple = new Tuple( table, null );
for ( SimpleValue value : values ) {
tuple.addValue( value );
}
return tuple;
}
else {
// assume a column named based on the NamingStrategy
final String name = metadata.getOptions()
.getNamingStrategy()
.propertyToColumnName( attributeBinding.getAttribute().getName() );
return table.locateOrCreateColumn( name );
final SimpleValueBinding valueBinding = new SimpleValueBinding();
valueBindings.add(
new SimpleValueBinding(
attributeBinding.getEntityBinding().getBaseTable().locateOrCreateColumn( name )
)
);
}
attributeBinding.setSimpleValueBindings( valueBindings );
}
private void processFetchProfiles(EntitySource entitySource, EntityBinding entityBinding) {

View File

@ -109,4 +109,6 @@ public interface ColumnSource extends RelationalValueSource {
*/
public String getComment();
public boolean isIncludedInInsert();
public boolean isIncludedInUpdate();
}

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc.
*
* 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.metamodel.source.binder;
/**
* Describes the nature of the collection elements as declared by the metadata.
*
* @author Steve Ebersole
*/
public enum PluralAttributeElementNature {
BASIC,
COMPONENT,
ONE_TO_MANY,
MANY_TO_MANY,
MANY_TO_ANY
}

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc.
*
* 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.metamodel.source.binder;
/**
* Describes the nature of the collection itself as declared by the metadata.
*
* @author Steve Ebersole
*/
public enum PluralAttributeNature {
BAG,
ID_BAG,
SET,
LIST,
MAP
}

View File

@ -21,17 +21,13 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding.state;
package org.hibernate.metamodel.source.binder;
/**
* @author Gail Badner
* @author Steve Ebersole
*/
public interface ManyToOneAttributeBindingState extends SimpleAttributeBindingState {
boolean isUnwrapProxy();
public interface PluralAttributeSource extends AttributeSource {
public PluralAttributeNature getPluralAttributeNature();
public PluralAttributeElementNature getPluralAttributeElementNature();
String getReferencedAttributeName();
String getReferencedEntityName();
boolean ignoreNotFound();
}

View File

@ -32,4 +32,10 @@ package org.hibernate.metamodel.source.binder;
* @see DerivedValueSource
*/
public interface RelationalValueSource {
/**
* Obtain the name of the table that contains this value.
*
* @return
*/
public String getContainingTableName();
}

View File

@ -31,6 +31,11 @@ import java.util.List;
* @author Steve Ebersole
*/
public interface RelationalValueSourceContainer {
public boolean areValuesIncludedInInsertByDefault();
public boolean areValuesIncludedInUpdateByDefault();
public boolean areValuesNullableByDefault();
/**
* Obtain the contained {@link RelationalValueSource} references.
*

View File

@ -30,6 +30,7 @@ package org.hibernate.metamodel.source.binder;
*/
public enum SingularAttributeNature {
BASIC,
COMPONENT,
MANY_TO_ONE,
ONE_TO_ONE,
ANY

View File

@ -49,4 +49,14 @@ public interface TableSource {
* @return The table name.
*/
public String getExplicitTableName();
/**
* Obtain the logical name of the table. This value is used to uniquely reference the table when binding
* values to the binding model.
*
* @return The logical name. Can be {@code null} in the case of the "primary table".
*
* @see RelationalValueSource#getContainingTableName()
*/
public String getLogicalName();
}

View File

@ -23,6 +23,8 @@
*/
package org.hibernate.metamodel.source.binder;
import org.hibernate.FetchMode;
/**
* Further contract for sources of {@code *-to-one} style associations.
*

View File

@ -31,10 +31,35 @@ import org.hibernate.metamodel.source.binder.ColumnSource;
* @author Steve Ebersole
*/
class ColumnAttributeSourceImpl implements ColumnSource {
private final String tableName;
private final String columnName;
private boolean includedInInsert;
private boolean includedInUpdate;
ColumnAttributeSourceImpl(String columnName) {
ColumnAttributeSourceImpl(
String tableName,
String columnName,
boolean includedInInsert,
boolean includedInUpdate) {
this.tableName = tableName;
this.columnName = columnName;
this.includedInInsert = includedInInsert;
this.includedInUpdate = includedInUpdate;
}
@Override
public boolean isIncludedInInsert() {
return includedInInsert;
}
@Override
public boolean isIncludedInUpdate() {
return includedInUpdate;
}
@Override
public String getContainingTableName() {
return tableName;
}
@Override

View File

@ -25,16 +25,27 @@ package org.hibernate.metamodel.source.hbm;
import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.Size;
import org.hibernate.metamodel.source.binder.ColumnSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLColumnElement;
/**
* @author Steve Ebersole
*/
class ColumnSourceImpl implements org.hibernate.metamodel.source.binder.ColumnSource {
class ColumnSourceImpl implements ColumnSource {
private final String tableName;
private final XMLColumnElement columnElement;
private boolean includedInInsert;
private boolean includedInUpdate;
ColumnSourceImpl(XMLColumnElement columnElement) {
ColumnSourceImpl(
String tableName,
XMLColumnElement columnElement,
boolean isIncludedInInsert,
boolean isIncludedInUpdate) {
this.tableName = tableName;
this.columnElement = columnElement;
includedInInsert = isIncludedInInsert;
includedInUpdate = isIncludedInUpdate;
}
@Override
@ -97,4 +108,18 @@ class ColumnSourceImpl implements org.hibernate.metamodel.source.binder.ColumnSo
return columnElement.getComment();
}
@Override
public boolean isIncludedInInsert() {
return includedInInsert;
}
@Override
public boolean isIncludedInUpdate() {
return includedInUpdate;
}
@Override
public String getContainingTableName() {
return tableName;
}
}

View File

@ -29,9 +29,11 @@ import org.hibernate.metamodel.source.binder.DerivedValueSource;
* @author Steve Ebersole
*/
class FormulaImpl implements DerivedValueSource {
private String tableName;
private final String expression;
FormulaImpl(String expression) {
FormulaImpl(String tableName, String expression) {
this.tableName = tableName;
this.expression = expression;
}
@ -39,4 +41,9 @@ class FormulaImpl implements DerivedValueSource {
public String getExpression() {
return expression;
}
@Override
public String getContainingTableName() {
return tableName;
}
}

View File

@ -24,13 +24,11 @@
package org.hibernate.metamodel.source.hbm;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.CascadeStyle;
@ -61,8 +59,6 @@ import org.hibernate.service.classloading.spi.ClassLoadingException;
* @author Gail Badner
*/
public class Helper {
static final Iterable<CascadeStyle> NO_CASCADING = Collections.singleton( CascadeStyle.NONE );
public static final ExplicitHibernateTypeSource TO_ONE_ATTRIBUTE_TYPE_SOURCE = new ExplicitHibernateTypeSource() {
@Override
public String getName() {
@ -145,12 +141,6 @@ public class Helper {
return getStringValue( access, isEmbedded ? "embedded" : defaultAccess );
}
public static MetaAttributeContext extractMetaAttributeContext(
List<XMLMetaElement> metaElementList,
MetaAttributeContext parentContext) {
return extractMetaAttributeContext( metaElementList, false, parentContext );
}
public static MetaAttributeContext extractMetaAttributeContext(
List<XMLMetaElement> metaElementList,
boolean onlyInheritable,
@ -187,40 +177,10 @@ public class Helper {
return value == null ? defaultValue : Long.parseLong( value );
}
public static boolean getBooleanValue(String value, boolean defaultValue) {
return value == null ? defaultValue : Boolean.valueOf( value );
}
public static boolean getBooleanValue(Boolean value, boolean defaultValue) {
return value == null ? defaultValue : value;
}
public static Set<String> getStringValueTokens(String str, String delimiters) {
if ( str == null ) {
return Collections.emptySet();
}
else {
StringTokenizer tokenizer = new StringTokenizer( str, delimiters );
Set<String> tokens = new HashSet<String>();
while ( tokenizer.hasMoreTokens() ) {
tokens.add( tokenizer.nextToken() );
}
return tokens;
}
}
// todo : remove this once the state objects are cleaned up
public static Class classForName(String className, ServiceRegistry serviceRegistry) {
ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
try {
return classLoaderService.classForName( className );
}
catch ( ClassLoadingException e ) {
throw new MappingException( "Could not find class: " + className );
}
}
public static Iterable<CascadeStyle> interpretCascadeStyles(String cascades, LocalBindingContext bindingContext) {
final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>();
if ( StringHelper.isEmpty( cascades ) ) {
@ -274,6 +234,9 @@ public class Helper {
}
public static interface ValueSourcesAdapter {
public String getContainingTableName();
public boolean isIncludedInInsertByDefault();
public boolean isIncludedInUpdateByDefault();
public String getColumnAttribute();
public String getFormulaAttribute();
public List getColumnOrFormulaElements();
@ -298,7 +261,14 @@ public class Helper {
bindingContext.getOrigin()
);
}
result.add( new ColumnAttributeSourceImpl( valueSourcesAdapter.getColumnAttribute() ) );
result.add(
new ColumnAttributeSourceImpl(
valueSourcesAdapter.getContainingTableName(),
valueSourcesAdapter.getColumnAttribute(),
valueSourcesAdapter.isIncludedInInsertByDefault(),
valueSourcesAdapter.isIncludedInUpdateByDefault()
)
);
}
else if ( StringHelper.isNotEmpty( valueSourcesAdapter.getFormulaAttribute() ) ) {
if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
@ -309,19 +279,48 @@ public class Helper {
);
}
// column/formula attribute combo checked already
result.add( new FormulaImpl( valueSourcesAdapter.getFormulaAttribute() ) );
result.add(
new FormulaImpl(
valueSourcesAdapter.getContainingTableName(),
valueSourcesAdapter.getFormulaAttribute()
)
);
}
else if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
&& ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) {
for ( Object columnOrFormulaElement : valueSourcesAdapter.getColumnOrFormulaElements() ) {
if ( XMLColumnElement.class.isInstance( columnOrFormulaElement ) ) {
result.add( new ColumnSourceImpl( (XMLColumnElement) columnOrFormulaElement ) );
result.add(
new ColumnSourceImpl(
valueSourcesAdapter.getContainingTableName(),
(XMLColumnElement) columnOrFormulaElement,
valueSourcesAdapter.isIncludedInInsertByDefault(),
valueSourcesAdapter.isIncludedInUpdateByDefault()
)
);
}
else {
result.add( new FormulaImpl( (String) columnOrFormulaElement ) );
result.add(
new FormulaImpl(
valueSourcesAdapter.getContainingTableName(),
(String) columnOrFormulaElement
)
);
}
}
}
return result;
}
// todo : remove this once the state objects are cleaned up
public static Class classForName(String className, ServiceRegistry serviceRegistry) {
ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
try {
return classLoaderService.classForName( className );
}
catch ( ClassLoadingException e ) {
throw new MappingException( "Could not find class: " + className );
}
}
}

View File

@ -25,6 +25,7 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
@ -64,6 +65,22 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
public List getColumnOrFormulaElements() {
return manyToOneElement.getColumnOrFormula();
}
@Override
public String getContainingTableName() {
// todo : need to implement this...
return null;
}
@Override
public boolean isIncludedInInsertByDefault() {
return manyToOneElement.isInsert();
}
@Override
public boolean isIncludedInUpdateByDefault() {
return manyToOneElement.isUpdate();
}
},
bindingContext
);
@ -114,6 +131,13 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext );
}
@Override
public FetchMode getFetchMode() {
return manyToOneElement.getFetch() == null
? FetchMode.DEFAULT
: FetchMode.valueOf( manyToOneElement.getFetch().value() );
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.MANY_TO_ONE;
@ -124,6 +148,21 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
return false;
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return manyToOneElement.isInsert();
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return manyToOneElement.isUpdate();
}
@Override
public boolean areValuesNullableByDefault() {
return ! Helper.getBooleanValue( manyToOneElement.isNotNull(), false );
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;

View File

@ -26,7 +26,6 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
@ -84,6 +83,22 @@ class PropertyAttributeSourceImpl implements SingularAttributeSource {
public List getColumnOrFormulaElements() {
return propertyElement.getColumnOrFormula();
}
@Override
public String getContainingTableName() {
// todo : need to implement this...
return null;
}
@Override
public boolean isIncludedInInsertByDefault() {
return propertyElement.isInsert();
}
@Override
public boolean isIncludedInUpdateByDefault() {
return propertyElement.isUpdate();
}
},
bindingContext
);
@ -139,6 +154,21 @@ class PropertyAttributeSourceImpl implements SingularAttributeSource {
return false;
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return Helper.getBooleanValue( propertyElement.isInsert(), true );
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return Helper.getBooleanValue( propertyElement.isUpdate(), true );
}
@Override
public boolean areValuesNullableByDefault() {
return ! Helper.getBooleanValue( propertyElement.isNotNull(), false );
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;

View File

@ -173,6 +173,12 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
public String getExplicitTableName() {
return entityElement().getTable();
}
@Override
public String getLogicalName() {
// logical name for the primary table is null
return null;
}
};
}
}

View File

@ -26,7 +26,6 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
@ -86,6 +85,22 @@ class SingularIdentifierAttributeSourceImpl implements SingularAttributeSource {
public List getColumnOrFormulaElements() {
return idElement.getColumn();
}
@Override
public String getContainingTableName() {
// by definition, the identifier should be bound to the primary table of the root entity
return null;
}
@Override
public boolean isIncludedInInsertByDefault() {
return true;
}
@Override
public boolean isIncludedInUpdateByDefault() {
return false;
}
},
bindingContext
);
@ -143,6 +158,21 @@ class SingularIdentifierAttributeSourceImpl implements SingularAttributeSource {
return false;
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return false;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;

View File

@ -55,6 +55,12 @@ public class SubclassEntitySourceImpl extends AbstractEntitySourceImpl implement
public String getExplicitTableName() {
return ( (XMLJoinedSubclassElement) entityElement() ).getTable();
}
@Override
public String getLogicalName() {
// logical name for the primary table is null
return null;
}
};
}
else if ( XMLUnionSubclassElement.class.isInstance( entityElement() ) ) {
@ -73,6 +79,12 @@ public class SubclassEntitySourceImpl extends AbstractEntitySourceImpl implement
public String getExplicitTableName() {
return ( (XMLUnionSubclassElement) entityElement() ).getTable();
}
@Override
public String getLogicalName() {
// logical name for the primary table is null
return null;
}
};
}
return null;

View File

@ -26,7 +26,6 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.internal.util.Value;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
@ -69,6 +68,22 @@ class TimestampAttributeSourceImpl implements SingularAttributeSource {
public List getColumnOrFormulaElements() {
return null;
}
@Override
public String getContainingTableName() {
// by definition the version should come from the primary table of the root entity.
return null;
}
@Override
public boolean isIncludedInInsertByDefault() {
return true;
}
@Override
public boolean isIncludedInUpdateByDefault() {
return true;
}
},
bindingContext
);
@ -154,6 +169,21 @@ class TimestampAttributeSourceImpl implements SingularAttributeSource {
return false;
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return true;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;

View File

@ -26,7 +26,6 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.internal.util.Value;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
@ -69,6 +68,22 @@ class VersionAttributeSourceImpl implements SingularAttributeSource {
public List getColumnOrFormulaElements() {
return versionElement.getColumn();
}
@Override
public String getContainingTableName() {
// by definition the version should come from the primary table of the root entity.
return null;
}
@Override
public boolean isIncludedInInsertByDefault() {
return versionElement.isInsert();
}
@Override
public boolean isIncludedInUpdateByDefault() {
return true;
}
},
bindingContext
);
@ -154,6 +169,21 @@ class VersionAttributeSourceImpl implements SingularAttributeSource {
return false;
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return true;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;

View File

@ -28,6 +28,7 @@ import java.util.Properties;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.HibernateTypeDescriptor;
import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.SimpleValue;
@ -135,17 +136,19 @@ class AttributeTypeResolver {
// todo : this can be made a lot smarter, but for now this will suffice. currently we only handle single value bindings
Value value = attributeBinding.getValue();
if ( SimpleValue.class.isInstance( value ) ) {
SimpleValue simpleValue = (SimpleValue) value;
if ( simpleValue.getDatatype() == null ) {
simpleValue.setDatatype(
new Datatype(
resolvedHibernateType.sqlTypes( metadata )[0],
resolvedHibernateType.getName(),
resolvedHibernateType.getReturnedClass()
)
);
if ( SingularAttribute.class.isInstance( attributeBinding.getAttribute() ) ) {
final Value value = SingularAttributeBinding.class.cast( attributeBinding ).getValue();
if ( SimpleValue.class.isInstance( value ) ) {
SimpleValue simpleValue = (SimpleValue) value;
if ( simpleValue.getDatatype() == null ) {
simpleValue.setDatatype(
new Datatype(
resolvedHibernateType.sqlTypes( metadata )[0],
resolvedHibernateType.getName(),
resolvedHibernateType.getReturnedClass()
)
);
}
}
}
}

View File

@ -51,6 +51,7 @@ import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.MetadataSourceProcessingOrder;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.SessionFactoryBuilder;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.source.MappingDefaults;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.MetadataImplementor;
@ -61,7 +62,6 @@ import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.domain.BasicType;
import org.hibernate.metamodel.domain.Type;
@ -106,7 +106,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
*/
private Map<String, EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();
private Map<String, PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
private Map<String, AbstractPluralAttributeBinding> collectionBindingMap = new HashMap<String, AbstractPluralAttributeBinding>();
private Map<String, FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>();
private Map<String, String> imports = new HashMap<String, String>();
private Map<String, TypeDef> typeDefs = new HashMap<String, TypeDef>();
@ -414,16 +414,16 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
entityBindingMap.put( entityName, entityBinding );
}
public PluralAttributeBinding getCollection(String collectionRole) {
public AbstractPluralAttributeBinding getCollection(String collectionRole) {
return collectionBindingMap.get( collectionRole );
}
@Override
public Iterable<PluralAttributeBinding> getCollectionBindings() {
public Iterable<AbstractPluralAttributeBinding> getCollectionBindings() {
return collectionBindingMap.values();
}
public void addCollection(PluralAttributeBinding pluralAttributeBinding) {
public void addCollection(AbstractPluralAttributeBinding pluralAttributeBinding) {
final String owningEntityName = pluralAttributeBinding.getEntityBinding().getEntity().getName();
final String attributeName = pluralAttributeBinding.getAttribute().getName();
final String collectionRole = owningEntityName + '.' + attributeName;

View File

@ -97,8 +97,11 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metamodel.binding.AttributeBinding;
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.Value;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.property.BackrefPropertyAccessor;
import org.hibernate.sql.Alias;
@ -788,7 +791,7 @@ public abstract class AbstractEntityPersister
// IDENTIFIER
identifierColumnSpan = entityBinding.getEntityIdentifier().getValueBinding().getValuesSpan();
identifierColumnSpan = entityBinding.getEntityIdentifier().getValueBinding().getSimpleValueSpan();
rootTableKeyColumnNames = new String[identifierColumnSpan];
rootTableKeyColumnReaders = new String[identifierColumnSpan];
rootTableKeyColumnReaderTemplates = new String[identifierColumnSpan];
@ -818,14 +821,11 @@ public abstract class AbstractEntityPersister
// VERSION
if ( entityBinding.isVersioned() ) {
// Use AttributeBinding.getValues() due to HHH-6380
Iterator<SimpleValue> valueIterator = entityBinding.getVersioningValueBinding().getValues().iterator();
SimpleValue versionValue = valueIterator.next();
if ( ! ( versionValue instanceof org.hibernate.metamodel.relational.Column ) || valueIterator.hasNext() ) {
throw new MappingException( "Version must be a single column value." );
final Value versioningValue = entityBinding.getVersioningValueBinding().getValue();
if ( ! org.hibernate.metamodel.relational.Column.class.isInstance( versioningValue ) ) {
throw new AssertionFailure( "Bad versioning attribute binding : " + versioningValue );
}
org.hibernate.metamodel.relational.Column versionColumn =
( org.hibernate.metamodel.relational.Column ) versionValue;
org.hibernate.metamodel.relational.Column versionColumn = org.hibernate.metamodel.relational.Column.class.cast( versioningValue );
versionColumnName = versionColumn.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() );
}
else {
@ -863,35 +863,50 @@ public abstract class AbstractEntityPersister
i = 0;
boolean foundFormula = false;
for ( AttributeBinding prop : entityBinding.getAttributeBindingClosure() ) {
if ( prop == entityBinding.getEntityIdentifier().getValueBinding() ) {
for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) {
if ( attributeBinding == entityBinding.getEntityIdentifier().getValueBinding() ) {
// entity identifier is not considered a "normal" property
continue;
}
thisClassProperties.add( prop );
if ( ! attributeBinding.getAttribute().isSingular() ) {
// collections handled separately
continue;
}
int span = prop.getValuesSpan();
final SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding;
thisClassProperties.add( singularAttributeBinding );
propertySubclassNames[i] = singularAttributeBinding.getEntityBinding().getEntity().getName();
int span = singularAttributeBinding.getSimpleValueSpan();
propertyColumnSpans[i] = span;
propertySubclassNames[i] = prop.getEntityBinding().getEntity().getName();
String[] colNames = new String[span];
String[] colAliases = new String[span];
String[] colReaderTemplates = new String[span];
String[] colWriters = new String[span];
String[] formulaTemplates = new String[span];
boolean[] propertyColumnInsertability = new boolean[span];
boolean[] propertyColumnUpdatability = new boolean[span];
int k = 0;
for ( SimpleValue thing : prop.getValues() ) {
colAliases[k] = thing.getAlias( factory.getDialect() );
if ( thing instanceof DerivedValue ) {
for ( SimpleValueBinding valueBinding : singularAttributeBinding.getSimpleValueBindings() ) {
colAliases[k] = valueBinding.getSimpleValue().getAlias( factory.getDialect() );
if ( valueBinding.isDerived() ) {
foundFormula = true;
formulaTemplates[ k ] = getTemplateFromString( ( (DerivedValue) thing ).getExpression(), factory );
formulaTemplates[ k ] = getTemplateFromString( ( (DerivedValue) valueBinding.getSimpleValue() ).getExpression(), factory );
}
else {
org.hibernate.metamodel.relational.Column col = ( org.hibernate.metamodel.relational.Column ) thing;
org.hibernate.metamodel.relational.Column col = ( org.hibernate.metamodel.relational.Column ) valueBinding.getSimpleValue();
colNames[k] = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() );
colReaderTemplates[k] = getTemplateFromColumn( col, factory );
colWriters[k] = col.getWriteFragment() == null ? "?" : col.getWriteFragment();
}
propertyColumnInsertability[k] = valueBinding.isIncludeInInsert();
propertyColumnUpdatability[k] = valueBinding.isIncludeInUpdate();
k++;
}
propertyColumnNames[i] = colNames;
@ -900,22 +915,23 @@ public abstract class AbstractEntityPersister
propertyColumnWriters[i] = colWriters;
propertyColumnAliases[i] = colAliases;
if ( lazyAvailable && prop.isLazy() ) {
lazyProperties.add( prop.getAttribute().getName() );
lazyNames.add( prop.getAttribute().getName() );
propertyColumnUpdateable[i] = propertyColumnInsertability;
propertyColumnInsertable[i] = propertyColumnUpdatability;
if ( lazyAvailable && singularAttributeBinding.isLazy() ) {
lazyProperties.add( singularAttributeBinding.getAttribute().getName() );
lazyNames.add( singularAttributeBinding.getAttribute().getName() );
lazyNumbers.add( i );
lazyTypes.add( prop.getHibernateTypeDescriptor().getResolvedTypeMapping());
lazyTypes.add( singularAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping());
lazyColAliases.add( colAliases );
}
propertyColumnUpdateable[i] = prop.getColumnUpdateability();
propertyColumnInsertable[i] = prop.getColumnInsertability();
// TODO: fix this when backrefs are working
//propertySelectable[i] = prop.isBackRef();
//propertySelectable[i] = singularAttributeBinding.isBackRef();
propertySelectable[i] = true;
propertyUniqueness[i] = prop.isAlternateUniqueKey();
propertyUniqueness[i] = singularAttributeBinding.isAlternateUniqueKey();
i++;

View File

@ -50,6 +50,8 @@ 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;
@ -643,6 +645,9 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
if ( attributeBinding == entityBinding.getEntityIdentifier().getValueBinding() ) {
continue; // skip identifier binding
}
if ( ! attributeBinding.getAttribute().isSingular() ) {
continue;
}
propertyTableNumbers[ i++ ] = 0;
}
@ -654,20 +659,25 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
// TODO: fix when subclasses are working (HHH-6337)
//for ( AttributeBinding prop : entityBinding.getSubclassAttributeBindingClosure() ) {
for ( AttributeBinding prop : entityBinding.getAttributeBindingClosure() ) {
for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) {
if ( ! attributeBinding.getAttribute().isSingular() ) {
continue;
}
SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding;
// TODO: fix when joins are working (HHH-6391)
//int join = entityBinding.getJoinNumber(prop);
//int join = entityBinding.getJoinNumber(singularAttributeBinding);
int join = 0;
propertyJoinNumbers.add(join);
//propertyTableNumbersByName.put( prop.getName(), join );
//propertyTableNumbersByName.put( singularAttributeBinding.getName(), join );
propertyTableNumbersByNameAndSubclass.put(
prop.getEntityBinding().getEntity().getName() + '.' + prop.getAttribute().getName(),
singularAttributeBinding.getEntityBinding().getEntity().getName() + '.' + singularAttributeBinding.getAttribute().getName(),
join
);
for ( SimpleValue simpleValue : prop.getValues() ) {
if ( DerivedValue.class.isInstance( simpleValue ) ) {
for ( SimpleValueBinding simpleValueBinding : singularAttributeBinding.getSimpleValueBindings() ) {
if ( DerivedValue.class.isInstance( simpleValueBinding.getSimpleValue() ) ) {
formulaJoinedNumbers.add( join );
}
else {

View File

@ -34,7 +34,7 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.spi.PersisterClassResolver;
@ -95,7 +95,7 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
/**
* The constructor signature for {@link CollectionPersister} implementations using
* a {@link PluralAttributeBinding}
* a {@link org.hibernate.metamodel.binding.AbstractPluralAttributeBinding}
*
* @todo still need to make collection persisters EntityMode-aware
* @todo make EntityPersister *not* depend on {@link SessionFactoryImplementor} if possible.
@ -103,7 +103,7 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
* when new metamodel is integrated
*/
private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS_NEW = new Class[] {
PluralAttributeBinding.class,
AbstractPluralAttributeBinding.class,
CollectionRegionAccessStrategy.class,
MetadataImplementor.class,
SessionFactoryImplementor.class
@ -198,7 +198,7 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
@Override
@SuppressWarnings( {"unchecked"})
public CollectionPersister createCollectionPersister(MetadataImplementor metadata,
PluralAttributeBinding collectionMetadata,
AbstractPluralAttributeBinding collectionMetadata,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException {
Class<? extends CollectionPersister> persisterClass = collectionMetadata.getCollectionPersisterClass();
@ -209,7 +209,7 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
return create( persisterClass, COLLECTION_PERSISTER_CONSTRUCTOR_ARGS_NEW, metadata, collectionMetadata, cacheAccessStrategy, factory );
}
// TODO: change collectionMetadata arg type to PluralAttributeBinding when new metadata is integrated
// TODO: change collectionMetadata arg type to AbstractPluralAttributeBinding when new metadata is integrated
// TODO: change metadata arg type to MetadataImplementor when new metadata is integrated
private static CollectionPersister create(
Class<? extends CollectionPersister> persisterClass,

View File

@ -28,8 +28,9 @@ import org.hibernate.mapping.JoinedSubclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.UnionSubclass;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.CollectionElementNature;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.collection.BasicCollectionPersister;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.collection.OneToManyPersister;
@ -107,8 +108,10 @@ public class StandardPersisterClassResolver implements PersisterClassResolver {
}
@Override
public Class<? extends CollectionPersister> getCollectionPersisterClass(PluralAttributeBinding metadata) {
return metadata.getCollectionElement().isOneToMany() ? oneToManyPersister() : basicCollectionPersister();
public Class<? extends CollectionPersister> getCollectionPersisterClass(AbstractPluralAttributeBinding metadata) {
return metadata.getCollectionElement().getCollectionElementNature() == CollectionElementNature.ONE_TO_MANY
? oneToManyPersister()
: basicCollectionPersister();
}
private Class<OneToManyPersister> oneToManyPersister() {

View File

@ -25,8 +25,8 @@ package org.hibernate.persister.spi;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.Service;
@ -80,5 +80,5 @@ public interface PersisterClassResolver extends Service {
*
* @return The collection persister class to use
*/
Class<? extends CollectionPersister> getCollectionPersisterClass(PluralAttributeBinding metadata);
Class<? extends CollectionPersister> getCollectionPersisterClass(AbstractPluralAttributeBinding metadata);
}

View File

@ -33,7 +33,7 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.Service;
@ -122,7 +122,7 @@ public interface PersisterFactory extends Service {
*/
public CollectionPersister createCollectionPersister(
MetadataImplementor metadata,
PluralAttributeBinding model,
AbstractPluralAttributeBinding model,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException;

View File

@ -35,10 +35,12 @@ import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.binding.AssociationAttributeBinding;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.SimpleSingularAttributeBinding;
import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.property.Getter;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.PropertyAccessorFactory;
@ -106,7 +108,7 @@ public class PropertyFactory {
*/
public static IdentifierProperty buildIdentifierProperty(EntityBinding mappedEntity, IdentifierGenerator generator) {
final SimpleAttributeBinding property = mappedEntity.getEntityIdentifier().getValueBinding();
final SimpleSingularAttributeBinding property = mappedEntity.getEntityIdentifier().getValueBinding();
// TODO: the following will cause an NPE with "virtual" IDs; how should they be set?
final String mappedUnsavedValue = property.getUnsavedValue();
@ -186,7 +188,7 @@ public class PropertyFactory {
* @param lazyAvailable Is property lazy loading currently available.
* @return The appropriate VersionProperty definition.
*/
public static VersionProperty buildVersionProperty(SimpleAttributeBinding property, boolean lazyAvailable) {
public static VersionProperty buildVersionProperty(SimpleSingularAttributeBinding property, boolean lazyAvailable) {
String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
@ -198,21 +200,24 @@ public class PropertyFactory {
boolean lazy = lazyAvailable && property.isLazy();
final CascadeStyle cascadeStyle = property.isAssociation()
? ( (AssociationAttributeBinding) property ).getCascadeStyle()
: CascadeStyle.NONE;
return new VersionProperty(
property.getAttribute().getName(),
null,
property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
lazy,
property.isInsertable(),
property.isUpdatable(),
property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
true, // insertable
true, // updatable
property.getGeneration() == PropertyGeneration.INSERT
|| property.getGeneration() == PropertyGeneration.ALWAYS,
property.getGeneration() == PropertyGeneration.ALWAYS,
property.isNullable(),
property.isUpdatable() && !lazy,
property.isOptimisticLockable(),
// TODO: get cascadeStyle from property when HHH-6355 is fixed; for now, assume NONE
//property.getCascadeStyle(),
CascadeStyle.NONE,
!lazy,
property.isIncludedInOptimisticLocking(),
cascadeStyle,
unsavedValue
);
}
@ -275,57 +280,63 @@ public class PropertyFactory {
// to update the cache (not the database), since in this case a null
// entity reference can lose information
boolean alwaysDirtyCheck = type.isAssociationType() &&
( (AssociationType) type ).isAlwaysDirtyChecked();
final boolean alwaysDirtyCheck = type.isAssociationType() && ( (AssociationType) type ).isAlwaysDirtyChecked();
if ( property.getAttribute().isSingular() ) {
final SingularAttributeBinding singularAttributeBinding = ( SingularAttributeBinding ) property;
final CascadeStyle cascadeStyle = singularAttributeBinding.isAssociation()
? ( (AssociationAttributeBinding) singularAttributeBinding ).getCascadeStyle()
: CascadeStyle.NONE;
final FetchMode fetchMode = singularAttributeBinding.isAssociation()
? ( (AssociationAttributeBinding) singularAttributeBinding ).getFetchMode()
: FetchMode.DEFAULT;
if ( property.isSimpleValue() ) {
SimpleAttributeBinding simpleProperty = ( SimpleAttributeBinding ) property;
return new StandardProperty(
simpleProperty.getAttribute().getName(),
singularAttributeBinding.getAttribute().getName(),
null,
type,
lazyAvailable && simpleProperty.isLazy(),
simpleProperty.isInsertable(),
simpleProperty.isUpdatable(),
simpleProperty.getGeneration() == PropertyGeneration.INSERT || simpleProperty.getGeneration() == PropertyGeneration.ALWAYS,
simpleProperty.getGeneration() == PropertyGeneration.ALWAYS,
simpleProperty.isNullable(),
alwaysDirtyCheck || simpleProperty.isUpdatable(),
simpleProperty.isOptimisticLockable(),
// TODO: get cascadeStyle from simpleProperty when HHH-6355 is fixed; for now, assume NONE
//simpleProperty.getCascadeStyle(),
CascadeStyle.NONE,
// TODO: get fetchMode() from simpleProperty when HHH-6357 is fixed; for now, assume FetchMode.DEFAULT
//simpleProperty.getFetchMode()
FetchMode.DEFAULT
);
lazyAvailable && singularAttributeBinding.isLazy(),
true, // insertable
true, // updatable
singularAttributeBinding.getGeneration() == PropertyGeneration.INSERT
|| singularAttributeBinding.getGeneration() == PropertyGeneration.ALWAYS,
singularAttributeBinding.getGeneration() == PropertyGeneration.ALWAYS,
singularAttributeBinding.isNullable(),
alwaysDirtyCheck,
singularAttributeBinding.isIncludedInOptimisticLocking(),
cascadeStyle,
fetchMode
);
}
else {
PluralAttributeBinding pluralProperty = ( PluralAttributeBinding ) property;
final AbstractPluralAttributeBinding pluralAttributeBinding = (AbstractPluralAttributeBinding) property;
final CascadeStyle cascadeStyle = pluralAttributeBinding.isAssociation()
? ( (AssociationAttributeBinding) pluralAttributeBinding ).getCascadeStyle()
: CascadeStyle.NONE;
final FetchMode fetchMode = pluralAttributeBinding.isAssociation()
? ( (AssociationAttributeBinding) pluralAttributeBinding ).getFetchMode()
: FetchMode.DEFAULT;
return new StandardProperty(
pluralProperty.getAttribute().getName(),
pluralAttributeBinding.getAttribute().getName(),
null,
type,
lazyAvailable && pluralProperty.isLazy(),
// TODO: fix this when HHH-6356 is fixed; for now assume PluralAttributeBinding is updatable and insertable
// pluralProperty.isInsertable(),
//pluralProperty.isUpdatable(),
lazyAvailable && pluralAttributeBinding.isLazy(),
// TODO: fix this when HHH-6356 is fixed; for now assume AbstractPluralAttributeBinding is updatable and insertable
// pluralAttributeBinding.isInsertable(),
//pluralAttributeBinding.isUpdatable(),
true,
true,
false,
false,
pluralProperty.isNullable(),
// TODO: fix this when HHH-6356 is fixed; for now assume PluralAttributeBinding is updatable and insertable
//alwaysDirtyCheck || pluralProperty.isUpdatable(),
// pluralAttributeBinding.isNullable(),
false, // nullable - not sure what that means for a collection
// TODO: fix this when HHH-6356 is fixed; for now assume AbstractPluralAttributeBinding is updatable and insertable
//alwaysDirtyCheck || pluralAttributeBinding.isUpdatable(),
true,
pluralProperty.isOptimisticLocked(),
// TODO: get cascadeStyle from property when HHH-6355 is fixed; for now, assume NONE
//pluralProperty.getCascadeStyle(),
CascadeStyle.NONE,
// TODO: get fetchMode() from simpleProperty when HHH-6357 is fixed; for now, assume FetchMode.DEFAULT
//pluralProperty.getFetchMode()
FetchMode.DEFAULT
pluralAttributeBinding.isIncludedInOptimisticLocking(),
cascadeStyle,
fetchMode
);
}
}

View File

@ -52,10 +52,9 @@ import org.hibernate.mapping.Property;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.binding.SimpleSingularAttributeBinding;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.domain.TypeNature;
import org.hibernate.tuple.IdentifierProperty;
import org.hibernate.tuple.PropertyFactory;
import org.hibernate.tuple.StandardProperty;
@ -387,8 +386,8 @@ public class EntityMetamodel implements Serializable {
boolean hasLazy = false;
// TODO: Fix after HHH-6337 is fixed; for now assume entityBinding is the root binding
//SimpleAttributeBinding rootEntityIdentifier = entityBinding.getRootEntityBinding().getEntityIdentifier().getValueBinding();
SimpleAttributeBinding rootEntityIdentifier = entityBinding.getEntityIdentifier().getValueBinding();
//SimpleSingularAttributeBinding rootEntityIdentifier = entityBinding.getRootEntityBinding().getEntityIdentifier().getValueBinding();
SimpleSingularAttributeBinding rootEntityIdentifier = entityBinding.getEntityIdentifier().getValueBinding();
// entityBinding.getAttributeClosureSpan() includes the identifier binding;
// "properties" here excludes the ID, so subtract 1 if the identifier binding is non-null
propertySpan = rootEntityIdentifier == null ?

View File

@ -140,35 +140,32 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
assertTrue( idAttributeBinding.getAttribute().isSingular() );
assertNotNull( idAttributeBinding.getAttribute() );
SingularAttributeBinding singularIdAttributeBinding = (SingularAttributeBinding) idAttributeBinding;
SingularAttribute singularIdAttribute = ( SingularAttribute ) idAttributeBinding.getAttribute();
BasicType basicIdAttributeType = ( BasicType ) singularIdAttribute.getSingularAttributeType();
assertSame( Long.class, basicIdAttributeType.getClassReference() );
assertNotNull( idAttributeBinding.getValue() );
assertTrue( idAttributeBinding.getValue() instanceof Column );
Datatype idDataType = ( (Column) idAttributeBinding.getValue() ).getDatatype();
assertNotNull( singularIdAttributeBinding.getValue() );
assertTrue( singularIdAttributeBinding.getValue() instanceof Column );
Datatype idDataType = ( (Column) singularIdAttributeBinding.getValue() ).getDatatype();
assertSame( Long.class, idDataType.getJavaType() );
assertSame( Types.BIGINT, idDataType.getTypeCode() );
assertSame( LongType.INSTANCE.getName(), idDataType.getTypeName() );
AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" );
assertNotNull( nameBinding );
assertNotNull( entityBinding.getAttributeBinding( "name" ) );
assertNotNull( entityBinding.getAttributeBinding( "name" ).getAttribute() );
assertTrue( entityBinding.getAttributeBinding( "name" ).getAttribute().isSingular() );
SingularAttributeBinding nameBinding = (SingularAttributeBinding) entityBinding.getAttributeBinding( "name" );
assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
assertNotNull( nameBinding.getAttribute() );
assertNotNull( nameBinding.getValue() );
assertTrue( nameBinding.getAttribute().isSingular() );
assertNotNull( nameBinding.getAttribute() );
SingularAttribute singularNameAttribute = ( SingularAttribute ) nameBinding.getAttribute();
BasicType basicNameAttributeType = ( BasicType ) singularNameAttribute.getSingularAttributeType();
assertSame( String.class, basicNameAttributeType.getClassReference() );
assertNotNull( nameBinding.getValue() );
// until HHH-6380 is fixed, need to call getValues()
assertEquals( 1, nameBinding.getValuesSpan() );
Iterator<SimpleValue> it = nameBinding.getValues().iterator();
assertTrue( it.hasNext() );
SimpleValue nameValue = it.next();
SimpleValue nameValue = (SimpleValue) nameBinding.getValue();
assertTrue( nameValue instanceof Column );
Datatype nameDataType = nameValue.getDatatype();
assertSame( String.class, nameDataType.getJavaType() );

View File

@ -60,7 +60,7 @@ public class SimpleValueBindingTests extends BaseUnitTestCase {
entityBinding.setBaseTable( table );
SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute );
SimpleSingularAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute );
attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( "long" );
assertSame( idAttribute, attributeBinding.getAttribute() );

View File

@ -33,6 +33,7 @@ import org.junit.Test;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.domain.NonEntity;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.testing.FailureExpected;
@ -53,7 +54,7 @@ public class MappedSuperclassTests extends BaseAnnotationBindingTestCase {
// @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class })
public void testSimpleAttributeOverrideInMappedSuperclass() {
EntityBinding binding = getEntityBinding( MyEntity.class );
AttributeBinding nameBinding = binding.getAttributeBinding( "name" );
SingularAttributeBinding nameBinding = (SingularAttributeBinding) binding.getAttributeBinding( "name" );
assertNotNull( "the name attribute should be bound to MyEntity", nameBinding );
Column column = (Column) nameBinding.getValue();
@ -64,7 +65,7 @@ public class MappedSuperclassTests extends BaseAnnotationBindingTestCase {
// @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class })
public void testLastAttributeOverrideWins() {
EntityBinding binding = getEntityBinding( MyEntity.class );
AttributeBinding fooBinding = binding.getAttributeBinding( "foo" );
SingularAttributeBinding fooBinding = (SingularAttributeBinding) binding.getAttributeBinding( "foo" );
assertNotNull( "the foo attribute should be bound to MyEntity", fooBinding );
Column column = (Column) fooBinding.getValue();

View File

@ -45,8 +45,8 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
@ -76,7 +76,7 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
}
@Override
public Class<? extends CollectionPersister> getCollectionPersisterClass(PluralAttributeBinding metadata) {
public Class<? extends CollectionPersister> getCollectionPersisterClass(AbstractPluralAttributeBinding metadata) {
return NoopCollectionPersister.class;
}

View File

@ -45,7 +45,7 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.persister.internal.PersisterClassResolverInitiator;
import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.persister.collection.CollectionPersister;
@ -92,7 +92,7 @@ public class PersisterClassProviderTest extends junit.framework.TestCase {
}
@Override
public Class<? extends CollectionPersister> getCollectionPersisterClass(PluralAttributeBinding metadata) {
public Class<? extends CollectionPersister> getCollectionPersisterClass(AbstractPluralAttributeBinding metadata) {
return null;
}
}