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.cache.spi.CacheDataDescription;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.type.VersionType; 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( return new CacheDataDescriptionImpl(
model.isMutable(), model.isMutable(),
model.getEntityBinding().isVersioned(), model.getEntityBinding().isVersioned(),

View File

@ -114,7 +114,7 @@ import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata; import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.source.MetadataImplementor; import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.binding.EntityBinding; 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.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.Loadable;
@ -661,16 +661,16 @@ public final class SessionFactoryImpl
Map<String,Set<String>> tmpEntityToCollectionRoleMap = new HashMap<String,Set<String>>(); Map<String,Set<String>> tmpEntityToCollectionRoleMap = new HashMap<String,Set<String>>();
collectionPersisters = new HashMap(); collectionPersisters = new HashMap();
for ( PluralAttributeBinding model : metadata.getCollectionBindings() ) { for ( AbstractPluralAttributeBinding model : metadata.getCollectionBindings() ) {
if ( model.getAttribute() == null ) { 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() ) { if ( model.getAttribute().isSingular() ) {
throw new IllegalStateException( 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 String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
final AccessType accessType = AccessType.fromExternalName( model.getCacheConcurrencyStrategy() ); final AccessType accessType = AccessType.fromExternalName( model.getCacheConcurrencyStrategy() );
CollectionRegionAccessStrategy accessStrategy = null; 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.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile; import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator; import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding; import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef; import org.hibernate.metamodel.binding.TypeDef;
/** /**
@ -75,7 +75,7 @@ public interface Metadata {
*/ */
public EntityBinding getRootEntityBinding(String entityName); public EntityBinding getRootEntityBinding(String entityName);
public Iterable<PluralAttributeBinding> getCollectionBindings(); public Iterable<AbstractPluralAttributeBinding> getCollectionBindings();
public TypeDef getTypeDefinition(String name); public TypeDef getTypeDefinition(String name);

View File

@ -29,19 +29,12 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; 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.binding.state.AttributeBindingState;
import org.hibernate.metamodel.domain.Attribute; import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.relational.Column; import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.DerivedValue; import org.hibernate.metamodel.relational.DerivedValue;
import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Tuple; import org.hibernate.metamodel.source.MetaAttributeContext;
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;
/** /**
* Basic support for {@link AttributeBinding} implementors * Basic support for {@link AttributeBinding} implementors
@ -50,23 +43,22 @@ import org.hibernate.metamodel.relational.state.ValueRelationalState;
*/ */
public abstract class AbstractAttributeBinding implements AttributeBinding { public abstract class AbstractAttributeBinding implements AttributeBinding {
private final EntityBinding entityBinding; private final EntityBinding entityBinding;
private final Attribute attribute;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final Set<SingularAssociationAttributeBinding> entityReferencingAttributeBindings = new HashSet<SingularAssociationAttributeBinding>(); private final Set<SingularAssociationAttributeBinding> entityReferencingAttributeBindings = new HashSet<SingularAssociationAttributeBinding>();
private Attribute attribute; private boolean includedInOptimisticLocking;
private Value value;
private boolean isLazy; private boolean isLazy;
private String propertyAccessorName; private String propertyAccessorName;
private boolean isAlternateUniqueKey; private boolean isAlternateUniqueKey;
private Set<CascadeType> cascadeTypes;
private boolean optimisticLockable;
private MetaAttributeContext metaAttributeContext; private MetaAttributeContext metaAttributeContext;
protected AbstractAttributeBinding(EntityBinding entityBinding) { protected AbstractAttributeBinding(EntityBinding entityBinding, Attribute attribute) {
this.entityBinding = entityBinding; this.entityBinding = entityBinding;
this.attribute = attribute;
} }
protected void initialize(AttributeBindingState state) { protected void initialize(AttributeBindingState state) {
@ -74,10 +66,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
hibernateTypeDescriptor.setTypeParameters( state.getExplicitHibernateTypeParameters() ); hibernateTypeDescriptor.setTypeParameters( state.getExplicitHibernateTypeParameters() );
hibernateTypeDescriptor.setJavaTypeName( state.getJavaTypeName() ); hibernateTypeDescriptor.setJavaTypeName( state.getJavaTypeName() );
isLazy = state.isLazy(); isLazy = state.isLazy();
propertyAccessorName = state.getPropertyAccessorName();
isAlternateUniqueKey = state.isAlternateUniqueKey(); isAlternateUniqueKey = state.isAlternateUniqueKey();
cascadeTypes = state.getCascadeTypes();
optimisticLockable = state.isOptimisticLockable();
metaAttributeContext = state.getMetaAttributeContext(); metaAttributeContext = state.getMetaAttributeContext();
} }
@ -91,12 +80,32 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
return attribute; return attribute;
} }
protected void setAttribute(Attribute attribute) { @Override
this.attribute = attribute; public HibernateTypeDescriptor getHibernateTypeDescriptor() {
return hibernateTypeDescriptor;
} }
public void setValue(Value value) { @Override
this.value = value; 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() { protected boolean forceNonNullable() {
@ -111,100 +120,13 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
return this == getEntityBinding().getEntityIdentifier().getValueBinding(); 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 @Override
public MetaAttributeContext getMetaAttributeContext() { public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext; return metaAttributeContext;
} }
@Override public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) {
public int getValuesSpan() { this.metaAttributeContext = metaAttributeContext;
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;
} }
@Override @Override
@ -216,39 +138,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
this.isAlternateUniqueKey = alternateUniqueKey; 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 @Override
public boolean isLazy() { public boolean isLazy() {
return 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; package org.hibernate.metamodel.binding;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadeStyle;
/** /**
@ -32,11 +33,11 @@ import org.hibernate.engine.spi.CascadeStyle;
*/ */
public interface AssociationAttributeBinding extends AttributeBinding { 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. * Set the cascade styles in effect for this association.
@ -44,4 +45,8 @@ public interface AssociationAttributeBinding extends AttributeBinding {
* @param cascadeStyles The cascade styles. * @param cascadeStyles The cascade styles.
*/ */
public void setCascadeStyles(Iterable<CascadeStyle> cascadeStyles); 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 java.util.Set;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.domain.Attribute; import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.relational.Value;
/** /**
* 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 * @author Steve Ebersole
*/ */
@ -50,13 +48,6 @@ public interface AttributeBinding {
*/ */
public Attribute getAttribute(); 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. * Obtain the descriptor for the Hibernate {@link org.hibernate.type.Type} for this binding.
* <p/> * <p/>
@ -67,6 +58,18 @@ public interface AttributeBinding {
*/ */
public HibernateTypeDescriptor getHibernateTypeDescriptor(); 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 * Obtain the meta attributes associated with this binding
* *
@ -74,40 +77,10 @@ public interface AttributeBinding {
*/ */
public MetaAttributeContext getMetaAttributeContext(); 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 isAlternateUniqueKey();
public boolean isNullable();
public boolean[] getColumnUpdateability();
public boolean[] getColumnInsertability();
public boolean isSimpleValue();
public boolean isLazy(); public boolean isLazy();
public void addEntityReferencingAttributeBinding(SingularAssociationAttributeBinding attributeBinding); public void addEntityReferencingAttributeBinding(SingularAssociationAttributeBinding attributeBinding);

View File

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

View File

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

View File

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

View File

@ -21,23 +21,20 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.metamodel.binding.state; package org.hibernate.metamodel.binding;
import org.hibernate.mapping.PropertyGeneration;
/** /**
* Describes the nature of persistent collection elements.
*
* @author Steve Ebersole
* @author Gail Badner * @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 { public enum CollectionElementNature {
boolean isInsertable(); BASIC,
COMPOSITE,
boolean isUpdatable(); ONE_TO_MANY,
MANY_TO_MANY,
boolean isKeyCascadeDeleteEnabled(); MANY_TO_ANY
String getUnsavedValue();
public PropertyGeneration getPropertyGeneration();
} }

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 * @author Steve Ebersole
*/ */
public class CollectionKey { public class CollectionKey {
private final PluralAttributeBinding collection; private final AbstractPluralAttributeBinding collection;
private ForeignKey foreignKey; private ForeignKey foreignKey;
private boolean inverse; private boolean inverse;
private HibernateTypeDescriptor hibernateTypeDescriptor; private HibernateTypeDescriptor hibernateTypeDescriptor;
// todo : this would be nice to have but we do not always know it, especially in HBM case. // 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; this.collection = collection;
} }
} }

View File

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

View File

@ -28,14 +28,13 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.util.Value; import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Entity; import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.PluralAttribute; import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.TableSpecification; import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.source.MetaAttributeContext; import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
@ -65,7 +64,7 @@ public class EntityBinding {
private final EntityIdentifier entityIdentifier = new EntityIdentifier( this ); private final EntityIdentifier entityIdentifier = new EntityIdentifier( this );
private EntityDiscriminator entityDiscriminator; private EntityDiscriminator entityDiscriminator;
private SimpleAttributeBinding versionBinding; private SimpleSingularAttributeBinding versionBinding;
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>(); private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
@ -115,6 +114,11 @@ public class EntityBinding {
this.baseTable = baseTable; 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() { public boolean isRoot() {
return superEntityBinding == null; return superEntityBinding == null;
} }
@ -147,11 +151,11 @@ public class EntityBinding {
return versionBinding != null; return versionBinding != null;
} }
public void setVersionBinding(SimpleAttributeBinding versionBinding) { public void setVersionBinding(SimpleSingularAttributeBinding versionBinding) {
this.versionBinding = versionBinding; this.versionBinding = versionBinding;
} }
public SimpleAttributeBinding getVersioningValueBinding() { public SimpleSingularAttributeBinding getVersioningValueBinding() {
return versionBinding; return versionBinding;
} }
@ -201,47 +205,44 @@ public class EntityBinding {
return entityReferencingAttributeBindings; return entityReferencingAttributeBindings;
} }
public SimpleAttributeBinding makeSimpleIdAttributeBinding(Attribute attribute) { public SimpleSingularAttributeBinding makeSimpleIdAttributeBinding(SingularAttribute attribute) {
final SimpleAttributeBinding binding = makeSimpleAttributeBinding( attribute, true, true ); final SimpleSingularAttributeBinding binding = makeSimpleAttributeBinding( attribute, true, true );
getEntityIdentifier().setValueBinding( binding ); getEntityIdentifier().setValueBinding( binding );
return 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) { public SimpleSingularAttributeBinding makeVersionBinding(SingularAttribute 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) {
versionBinding = makeSimpleAttributeBinding( attribute, true, false ); versionBinding = makeSimpleAttributeBinding( attribute, true, false );
return versionBinding; return versionBinding;
} }
public SimpleAttributeBinding makeSimpleAttributeBinding(Attribute attribute) { public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute) {
return makeSimpleAttributeBinding( attribute, false, false ); return makeSimpleAttributeBinding( attribute, false, false );
} }
private SimpleAttributeBinding makeSimpleAttributeBinding(Attribute attribute, boolean forceNonNullable, boolean forceUnique) { private SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute, boolean forceNonNullable, boolean forceUnique) {
final SimpleAttributeBinding binding = new SimpleAttributeBinding( this, forceNonNullable, forceUnique ); final SimpleSingularAttributeBinding binding = new SimpleSingularAttributeBinding( this, attribute, forceNonNullable, forceUnique );
binding.setAttribute( attribute );
registerAttributeBinding( attribute.getName(), binding ); registerAttributeBinding( attribute.getName(), binding );
return binding; return binding;
} }
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(Attribute attribute) { public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this ); final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute );
binding.setAttribute( attribute );
registerAttributeBinding( attribute.getName(), binding ); registerAttributeBinding( attribute.getName(), binding );
return binding; return binding;
} }
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementType collectionElementType) { public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature) {
final BagBinding binding = new BagBinding( this, collectionElementType ); final BagBinding binding = new BagBinding( this, attribute, nature );
binding.setAttribute( attribute );
registerAttributeBinding( attribute.getName(), binding ); registerAttributeBinding( attribute.getName(), binding );
return binding; return binding;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * 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 * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc. * distributed under license by Red Hat Inc.
@ -23,219 +23,18 @@
*/ */
package org.hibernate.metamodel.binding; 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; import org.hibernate.metamodel.relational.Table;
/** /**
* TODO : javadoc
*
* @author Steve Ebersole * @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( public CollectionKey getCollectionKey();
CoreMessageLogger.class, PluralAttributeBinding.class.getName()
);
private Table collectionTable; public CollectionElement getCollectionElement();
private CollectionKey collectionKey; public Table getCollectionTable();
private final CollectionElement collectionElement;
// 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.PersistentIdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory; import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.mapping.PropertyGeneration; 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.domain.SingularAttribute;
import org.hibernate.metamodel.relational.state.ColumnRelationalState; import org.hibernate.metamodel.relational.state.ColumnRelationalState;
import org.hibernate.metamodel.relational.state.ValueRelationalState; import org.hibernate.metamodel.source.MetaAttributeContext;
/** /**
* TODO : javadoc * TODO : javadoc
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class SimpleAttributeBinding extends AbstractAttributeBinding implements SingularAttributeBinding, KeyValueBinding { public class SimpleSingularAttributeBinding
private boolean insertable; extends AbstractSingularAttributeBinding
private boolean updatable; implements SingularAttributeBinding, KeyValueBinding {
private PropertyGeneration generation;
private String propertyAccessorName;
private String unsavedValue; private String unsavedValue;
private PropertyGeneration generation;
private boolean includedInOptimisticLocking;
private boolean forceNonNullable; private boolean forceNonNullable;
private boolean forceUnique; private boolean forceUnique;
private boolean keyCascadeDeleteEnabled; private boolean keyCascadeDeleteEnabled;
private boolean includedInOptimisticLocking;
private MetaAttributeContext metaAttributeContext; private MetaAttributeContext metaAttributeContext;
SimpleAttributeBinding(EntityBinding entityBinding, boolean forceNonNullable, boolean forceUnique) { SimpleSingularAttributeBinding(
super( entityBinding ); EntityBinding entityBinding,
SingularAttribute attribute,
boolean forceNonNullable,
boolean forceUnique) {
super( entityBinding, attribute );
this.forceNonNullable = forceNonNullable; this.forceNonNullable = forceNonNullable;
this.forceUnique = forceUnique; this.forceUnique = forceUnique;
} }
public final SimpleAttributeBinding initialize(SimpleAttributeBindingState state) { @Override
super.initialize( state ); public boolean isAssociation() {
insertable = state.isInsertable(); return false;
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 @Override
public SingularAttribute getAttribute() { public String getUnsavedValue() {
return (SingularAttribute) super.getAttribute(); return unsavedValue;
}
public void setUnsavedValue(String unsavedValue) {
this.unsavedValue = unsavedValue;
} }
@Override @Override
public boolean isSimpleValue() { public PropertyGeneration getGeneration() {
return true; return generation;
} }
public boolean isInsertable() { public void setGeneration(PropertyGeneration generation) {
return insertable; this.generation = generation;
} }
public void setInsertable(boolean insertable) { public boolean isIncludedInOptimisticLocking() {
this.insertable = insertable; return includedInOptimisticLocking;
} }
public boolean isUpdatable() { public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking) {
return updatable; this.includedInOptimisticLocking = includedInOptimisticLocking;
}
public void setUpdatable(boolean updatable) {
this.updatable = updatable;
} }
@Override @Override
@ -117,15 +104,6 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
this.keyCascadeDeleteEnabled = keyCascadeDeleteEnabled; this.keyCascadeDeleteEnabled = keyCascadeDeleteEnabled;
} }
@Override
public String getUnsavedValue() {
return unsavedValue;
}
public void setUnsavedValue(String unsaveValue) {
this.unsavedValue = unsaveValue;
}
public boolean forceNonNullable() { public boolean forceNonNullable() {
return forceNonNullable; return forceNonNullable;
} }
@ -134,30 +112,6 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
return forceUnique; 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() { public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext; 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; 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 * @author Steve Ebersole
*/ */
public interface SingularAttributeBinding extends AttributeBinding { 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.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition; import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.metamodel.Metadata; import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile; import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator; import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef; import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.relational.AuxiliaryDatabaseObject;
import org.hibernate.metamodel.relational.Database; import org.hibernate.metamodel.relational.Database;
import org.hibernate.service.BasicServiceRegistry; import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.type.TypeResolver; import org.hibernate.type.TypeResolver;
@ -53,7 +52,7 @@ public interface MetadataImplementor extends Metadata, BindingContext, Mapping {
public void addEntity(EntityBinding entityBinding); public void addEntity(EntityBinding entityBinding);
public void addCollection(PluralAttributeBinding collectionBinding); public void addCollection(AbstractPluralAttributeBinding collectionBinding);
public void addFetchProfile(FetchProfile profile); public void addFetchProfile(FetchProfile profile);

View File

@ -102,6 +102,21 @@ public class ColumnSourceImpl implements ColumnSource {
// todo // todo
return null; 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 @Override
public boolean isVirtualAttribute() { public boolean isVirtualAttribute() {
return false; //To change body of implemented methods use File | Settings | File Templates. return false;
} }
@Override @Override
@ -72,7 +72,8 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
@Override @Override
public String getPropertyAccessorName() { public String getPropertyAccessorName() {
return null; //To change body of implemented methods use File | Settings | File Templates. // todo : implememt
return null;
} }
@Override @Override
@ -115,6 +116,21 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return true;
}
@Override @Override
public List<RelationalValueSource> relationalValueSources() { public List<RelationalValueSource> relationalValueSources() {
List<RelationalValueSource> valueSources = new ArrayList<RelationalValueSource>(); 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; 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.engine.spi.CascadeStyle;
import org.hibernate.metamodel.source.binder.SingularAttributeNature; import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.binder.ToOneAttributeSource; 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 { public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implements ToOneAttributeSource {
private final AssociationAttribute associationAttribute; private final AssociationAttribute associationAttribute;
private final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>();
public ToOneAttributeSourceImpl(AssociationAttribute associationAttribute) { public ToOneAttributeSourceImpl(AssociationAttribute associationAttribute) {
super( associationAttribute ); super( associationAttribute );
this.associationAttribute = associationAttribute; this.associationAttribute = associationAttribute;
for ( javax.persistence.CascadeType cascadeType : associationAttribute.getCascadeTypes() ) {
// todo : ...
}
} }
@Override @Override
@ -33,8 +63,14 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem
} }
@Override @Override
public Iterable<CascadeStyle> getCascadeStyle() { public Iterable<CascadeStyle> getCascadeStyles() {
return Collections.emptySet(); 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() { public String getExplicitTableName() {
return tableName; 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; package org.hibernate.metamodel.source.binder;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadeStyle;
/** /**
@ -37,4 +38,11 @@ public interface AssociationAttributeSource extends AttributeSource {
* @return The cascade styles. * @return The cascade styles.
*/ */
public Iterable<CascadeStyle> getCascadeStyles(); 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 boolean isSingular();
public String getPropertyAccessorName();
public boolean isIncludedInOptimisticLocking();
/** /**
* Obtain the meta-attribute sources associated with this attribute. * Obtain the meta-attribute sources associated with this attribute.
* *
* @return The meta-attribute sources. * @return The meta-attribute sources.
*/ */
public Iterable<MetaAttributeSource> metaAttributes(); public Iterable<MetaAttributeSource> metaAttributes();
} }

View File

@ -34,14 +34,20 @@ import org.hibernate.EntityMode;
import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.beans.BeanInfoHelper; 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.EntityBinding;
import org.hibernate.metamodel.binding.InheritanceType; import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.binding.ManyToOneAttributeBinding; import org.hibernate.metamodel.binding.ManyToOneAttributeBinding;
import org.hibernate.metamodel.binding.MetaAttribute; 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.binding.TypeDef;
import org.hibernate.metamodel.domain.Attribute; import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Entity; import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Column; import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Identifier; import org.hibernate.metamodel.relational.Identifier;
@ -278,19 +284,6 @@ public class Binder {
// Attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 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) { private void bindIdentifier(RootEntitySource entitySource, EntityBinding entityBinding) {
if ( entitySource.getIdentifierSource() == null ) { if ( entitySource.getIdentifierSource() == null ) {
throw new AssertionFailure( "Expecting identifier information on root entity descriptor" ); throw new AssertionFailure( "Expecting identifier information on root entity descriptor" );
@ -311,7 +304,7 @@ public class Binder {
} }
private void bindSimpleIdentifier(SimpleIdentifierSource identifierSource, EntityBinding entityBinding) { private void bindSimpleIdentifier(SimpleIdentifierSource identifierSource, EntityBinding entityBinding) {
final SimpleAttributeBinding idAttributeBinding = doBasicSingularAttributeBindingCreation( final SimpleSingularAttributeBinding idAttributeBinding = doBasicSingularAttributeBindingCreation(
identifierSource.getIdentifierAttributeSource(), entityBinding identifierSource.getIdentifierAttributeSource(), entityBinding
); );
@ -342,7 +335,7 @@ public class Binder {
return; return;
} }
SimpleAttributeBinding attributeBinding = doBasicSingularAttributeBindingCreation( SimpleSingularAttributeBinding attributeBinding = doBasicSingularAttributeBindingCreation(
versioningAttributeSource, entityBinding versioningAttributeSource, entityBinding
); );
entityBinding.setVersionBinding( attributeBinding ); entityBinding.setVersionBinding( attributeBinding );
@ -356,14 +349,58 @@ public class Binder {
// todo : implement // 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, SingularAttributeSource attributeSource,
EntityBinding entityBinding) { EntityBinding entityBinding) {
final SingularAttribute attribute = attributeSource.isVirtualAttribute() final SingularAttribute attribute = attributeSource.isVirtualAttribute()
? entityBinding.getEntity().locateOrCreateVirtualAttribute( attributeSource.getName() ) ? entityBinding.getEntity().locateOrCreateVirtualAttribute( attributeSource.getName() )
: entityBinding.getEntity().locateOrCreateSingularAttribute( attributeSource.getName() ); : entityBinding.getEntity().locateOrCreateSingularAttribute( attributeSource.getName() );
final SimpleAttributeBinding attributeBinding; final SimpleSingularAttributeBinding attributeBinding;
if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) { if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) {
attributeBinding = entityBinding.makeSimpleAttributeBinding( attribute ); attributeBinding = entityBinding.makeSimpleAttributeBinding( attribute );
resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding ); resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding );
@ -377,8 +414,6 @@ public class Binder {
throw new NotYetImplementedException(); throw new NotYetImplementedException();
} }
attributeBinding.setInsertable( attributeSource.isInsertable() );
attributeBinding.setUpdatable( attributeSource.isUpdatable() );
attributeBinding.setGeneration( attributeSource.getGeneration() ); attributeBinding.setGeneration( attributeSource.getGeneration() );
attributeBinding.setLazy( attributeSource.isLazy() ); attributeBinding.setLazy( attributeSource.isLazy() );
attributeBinding.setIncludedInOptimisticLocking( attributeSource.isIncludedInOptimisticLocking() ); attributeBinding.setIncludedInOptimisticLocking( attributeSource.isIncludedInOptimisticLocking() );
@ -391,8 +426,7 @@ public class Binder {
) )
); );
final org.hibernate.metamodel.relational.Value relationalValue = makeValue( attributeSource, attributeBinding ); bindRelationalValues( attributeSource, attributeBinding );
attributeBinding.setValue( relationalValue );
attributeBinding.setMetaAttributeContext( attributeBinding.setMetaAttributeContext(
buildMetaAttributeContext( attributeSource.metaAttributes(), entityBinding.getMetaAttributeContext() ) buildMetaAttributeContext( attributeSource.metaAttributes(), entityBinding.getMetaAttributeContext() )
@ -401,7 +435,7 @@ public class Binder {
return attributeBinding; return attributeBinding;
} }
private void resolveTypeInformation(ExplicitHibernateTypeSource typeSource, SimpleAttributeBinding attributeBinding) { private void resolveTypeInformation(ExplicitHibernateTypeSource typeSource, SimpleSingularAttributeBinding attributeBinding) {
final Class<?> attributeJavaType = determineJavaType( attributeBinding.getAttribute() ); final Class<?> attributeJavaType = determineJavaType( attributeBinding.getAttribute() );
if ( attributeJavaType != null ) { if ( attributeJavaType != null ) {
attributeBinding.getHibernateTypeDescriptor().setJavaTypeName( attributeJavaType.getName() ); attributeBinding.getHibernateTypeDescriptor().setJavaTypeName( attributeJavaType.getName() );
@ -472,6 +506,7 @@ public class Binder {
attributeBinding.setReferencedAttributeName( attributeSource.getReferencedEntityAttributeName() ); attributeBinding.setReferencedAttributeName( attributeSource.getReferencedEntityAttributeName() );
attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() ); attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() );
attributeBinding.setFetchMode( attributeSource.getFetchMode() );
} }
private MetaAttributeContext buildMetaAttributeContext(EntitySource entitySource) { private MetaAttributeContext buildMetaAttributeContext(EntitySource entitySource) {
@ -556,18 +591,17 @@ public class Binder {
// todo : implement // todo : implement
} }
private org.hibernate.metamodel.relational.Value makeValue( private void bindRelationalValues(
RelationalValueSourceContainer relationalValueSourceContainer, RelationalValueSourceContainer relationalValueSourceContainer,
SimpleAttributeBinding attributeBinding) { SingularAttributeBinding attributeBinding) {
// todo : to be completely correct, we need to know which table the value belongs to. List<SimpleValueBinding> valueBindings = new ArrayList<SimpleValueBinding>();
// 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();
if ( relationalValueSourceContainer.relationalValueSources().size() > 0 ) { if ( relationalValueSourceContainer.relationalValueSources().size() > 0 ) {
List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( RelationalValueSource valueSource : relationalValueSourceContainer.relationalValueSources() ) { for ( RelationalValueSource valueSource : relationalValueSourceContainer.relationalValueSources() ) {
final TableSpecification table = attributeBinding.getEntityBinding()
.getTable( valueSource.getContainingTableName() );
if ( ColumnSource.class.isInstance( valueSource ) ) { if ( ColumnSource.class.isInstance( valueSource ) ) {
final ColumnSource columnSource = ColumnSource.class.cast( valueSource ); final ColumnSource columnSource = ColumnSource.class.cast( valueSource );
final Column column = table.locateOrCreateColumn( columnSource.getName() ); final Column column = table.locateOrCreateColumn( columnSource.getName() );
@ -581,28 +615,35 @@ public class Binder {
column.setUnique( columnSource.isUnique() ); column.setUnique( columnSource.isUnique() );
column.setCheckCondition( columnSource.getCheckCondition() ); column.setCheckCondition( columnSource.getCheckCondition() );
column.setComment( columnSource.getComment() ); column.setComment( columnSource.getComment() );
values.add( column ); valueBindings.add(
new SimpleValueBinding(
column,
columnSource.isIncludedInInsert(),
columnSource.isIncludedInUpdate()
)
);
} }
else { 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 { else {
// assume a column named based on the NamingStrategy
final String name = metadata.getOptions() final String name = metadata.getOptions()
.getNamingStrategy() .getNamingStrategy()
.propertyToColumnName( attributeBinding.getAttribute().getName() ); .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) { private void processFetchProfiles(EntitySource entitySource, EntityBinding entityBinding) {

View File

@ -109,4 +109,6 @@ public interface ColumnSource extends RelationalValueSource {
*/ */
public String getComment(); 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 * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * 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 { public interface PluralAttributeSource extends AttributeSource {
boolean isUnwrapProxy(); 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 * @see DerivedValueSource
*/ */
public interface RelationalValueSource { 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 * @author Steve Ebersole
*/ */
public interface RelationalValueSourceContainer { public interface RelationalValueSourceContainer {
public boolean areValuesIncludedInInsertByDefault();
public boolean areValuesIncludedInUpdateByDefault();
public boolean areValuesNullableByDefault();
/** /**
* Obtain the contained {@link RelationalValueSource} references. * Obtain the contained {@link RelationalValueSource} references.
* *

View File

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

View File

@ -49,4 +49,14 @@ public interface TableSource {
* @return The table name. * @return The table name.
*/ */
public String getExplicitTableName(); 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; package org.hibernate.metamodel.source.binder;
import org.hibernate.FetchMode;
/** /**
* Further contract for sources of {@code *-to-one} style associations. * 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 * @author Steve Ebersole
*/ */
class ColumnAttributeSourceImpl implements ColumnSource { class ColumnAttributeSourceImpl implements ColumnSource {
private final String tableName;
private final String columnName; 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.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 @Override

View File

@ -25,16 +25,27 @@ package org.hibernate.metamodel.source.hbm;
import org.hibernate.metamodel.relational.Datatype; import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.Size; import org.hibernate.metamodel.relational.Size;
import org.hibernate.metamodel.source.binder.ColumnSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLColumnElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLColumnElement;
/** /**
* @author Steve Ebersole * @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 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; this.columnElement = columnElement;
includedInInsert = isIncludedInInsert;
includedInUpdate = isIncludedInUpdate;
} }
@Override @Override
@ -97,4 +108,18 @@ class ColumnSourceImpl implements org.hibernate.metamodel.source.binder.ColumnSo
return columnElement.getComment(); 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 * @author Steve Ebersole
*/ */
class FormulaImpl implements DerivedValueSource { class FormulaImpl implements DerivedValueSource {
private String tableName;
private final String expression; private final String expression;
FormulaImpl(String expression) { FormulaImpl(String tableName, String expression) {
this.tableName = tableName;
this.expression = expression; this.expression = expression;
} }
@ -39,4 +41,9 @@ class FormulaImpl implements DerivedValueSource {
public String getExpression() { public String getExpression() {
return expression; return expression;
} }
@Override
public String getContainingTableName() {
return tableName;
}
} }

View File

@ -24,13 +24,11 @@
package org.hibernate.metamodel.source.hbm; package org.hibernate.metamodel.source.hbm;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadeStyle;
@ -61,8 +59,6 @@ import org.hibernate.service.classloading.spi.ClassLoadingException;
* @author Gail Badner * @author Gail Badner
*/ */
public class Helper { public class Helper {
static final Iterable<CascadeStyle> NO_CASCADING = Collections.singleton( CascadeStyle.NONE );
public static final ExplicitHibernateTypeSource TO_ONE_ATTRIBUTE_TYPE_SOURCE = new ExplicitHibernateTypeSource() { public static final ExplicitHibernateTypeSource TO_ONE_ATTRIBUTE_TYPE_SOURCE = new ExplicitHibernateTypeSource() {
@Override @Override
public String getName() { public String getName() {
@ -145,12 +141,6 @@ public class Helper {
return getStringValue( access, isEmbedded ? "embedded" : defaultAccess ); return getStringValue( access, isEmbedded ? "embedded" : defaultAccess );
} }
public static MetaAttributeContext extractMetaAttributeContext(
List<XMLMetaElement> metaElementList,
MetaAttributeContext parentContext) {
return extractMetaAttributeContext( metaElementList, false, parentContext );
}
public static MetaAttributeContext extractMetaAttributeContext( public static MetaAttributeContext extractMetaAttributeContext(
List<XMLMetaElement> metaElementList, List<XMLMetaElement> metaElementList,
boolean onlyInheritable, boolean onlyInheritable,
@ -187,40 +177,10 @@ public class Helper {
return value == null ? defaultValue : Long.parseLong( value ); 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) { public static boolean getBooleanValue(Boolean value, boolean defaultValue) {
return value == null ? defaultValue : value; 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) { public static Iterable<CascadeStyle> interpretCascadeStyles(String cascades, LocalBindingContext bindingContext) {
final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>(); final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>();
if ( StringHelper.isEmpty( cascades ) ) { if ( StringHelper.isEmpty( cascades ) ) {
@ -274,6 +234,9 @@ public class Helper {
} }
public static interface ValueSourcesAdapter { public static interface ValueSourcesAdapter {
public String getContainingTableName();
public boolean isIncludedInInsertByDefault();
public boolean isIncludedInUpdateByDefault();
public String getColumnAttribute(); public String getColumnAttribute();
public String getFormulaAttribute(); public String getFormulaAttribute();
public List getColumnOrFormulaElements(); public List getColumnOrFormulaElements();
@ -298,7 +261,14 @@ public class Helper {
bindingContext.getOrigin() 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() ) ) { else if ( StringHelper.isNotEmpty( valueSourcesAdapter.getFormulaAttribute() ) ) {
if ( valueSourcesAdapter.getColumnOrFormulaElements() != null if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
@ -309,19 +279,48 @@ public class Helper {
); );
} }
// column/formula attribute combo checked already // 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 else if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
&& ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) { && ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) {
for ( Object columnOrFormulaElement : valueSourcesAdapter.getColumnOrFormulaElements() ) { for ( Object columnOrFormulaElement : valueSourcesAdapter.getColumnOrFormulaElements() ) {
if ( XMLColumnElement.class.isInstance( columnOrFormulaElement ) ) { if ( XMLColumnElement.class.isInstance( columnOrFormulaElement ) ) {
result.add( new ColumnSourceImpl( (XMLColumnElement) columnOrFormulaElement ) ); result.add(
new ColumnSourceImpl(
valueSourcesAdapter.getContainingTableName(),
(XMLColumnElement) columnOrFormulaElement,
valueSourcesAdapter.isIncludedInInsertByDefault(),
valueSourcesAdapter.isIncludedInUpdateByDefault()
)
);
} }
else { else {
result.add( new FormulaImpl( (String) columnOrFormulaElement ) ); result.add(
new FormulaImpl(
valueSourcesAdapter.getContainingTableName(),
(String) columnOrFormulaElement
)
);
} }
} }
} }
return result; 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 java.util.List;
import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext; import org.hibernate.metamodel.source.LocalBindingContext;
@ -64,6 +65,22 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
public List getColumnOrFormulaElements() { public List getColumnOrFormulaElements() {
return manyToOneElement.getColumnOrFormula(); 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 bindingContext
); );
@ -114,6 +131,13 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext ); return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext );
} }
@Override
public FetchMode getFetchMode() {
return manyToOneElement.getFetch() == null
? FetchMode.DEFAULT
: FetchMode.valueOf( manyToOneElement.getFetch().value() );
}
@Override @Override
public SingularAttributeNature getNature() { public SingularAttributeNature getNature() {
return SingularAttributeNature.MANY_TO_ONE; return SingularAttributeNature.MANY_TO_ONE;
@ -124,6 +148,21 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
return false; 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 @Override
public List<RelationalValueSource> relationalValueSources() { public List<RelationalValueSource> relationalValueSources() {
return valueSources; return valueSources;

View File

@ -26,7 +26,6 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext; import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource; import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
@ -84,6 +83,22 @@ class PropertyAttributeSourceImpl implements SingularAttributeSource {
public List getColumnOrFormulaElements() { public List getColumnOrFormulaElements() {
return propertyElement.getColumnOrFormula(); 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 bindingContext
); );
@ -139,6 +154,21 @@ class PropertyAttributeSourceImpl implements SingularAttributeSource {
return false; 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 @Override
public List<RelationalValueSource> relationalValueSources() { public List<RelationalValueSource> relationalValueSources() {
return valueSources; return valueSources;

View File

@ -173,6 +173,12 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
public String getExplicitTableName() { public String getExplicitTableName() {
return entityElement().getTable(); 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.List;
import java.util.Map; import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext; import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource; import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
@ -86,6 +85,22 @@ class SingularIdentifierAttributeSourceImpl implements SingularAttributeSource {
public List getColumnOrFormulaElements() { public List getColumnOrFormulaElements() {
return idElement.getColumn(); 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 bindingContext
); );
@ -143,6 +158,21 @@ class SingularIdentifierAttributeSourceImpl implements SingularAttributeSource {
return false; return false;
} }
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return false;
}
@Override @Override
public List<RelationalValueSource> relationalValueSources() { public List<RelationalValueSource> relationalValueSources() {
return valueSources; return valueSources;

View File

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

View File

@ -26,7 +26,6 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.internal.util.Value; import org.hibernate.internal.util.Value;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext; import org.hibernate.metamodel.source.LocalBindingContext;
@ -69,6 +68,22 @@ class TimestampAttributeSourceImpl implements SingularAttributeSource {
public List getColumnOrFormulaElements() { public List getColumnOrFormulaElements() {
return null; 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 bindingContext
); );
@ -154,6 +169,21 @@ class TimestampAttributeSourceImpl implements SingularAttributeSource {
return false; return false;
} }
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return true;
}
@Override @Override
public List<RelationalValueSource> relationalValueSources() { public List<RelationalValueSource> relationalValueSources() {
return valueSources; return valueSources;

View File

@ -26,7 +26,6 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.internal.util.Value; import org.hibernate.internal.util.Value;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext; import org.hibernate.metamodel.source.LocalBindingContext;
@ -69,6 +68,22 @@ class VersionAttributeSourceImpl implements SingularAttributeSource {
public List getColumnOrFormulaElements() { public List getColumnOrFormulaElements() {
return versionElement.getColumn(); 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 bindingContext
); );
@ -154,6 +169,21 @@ class VersionAttributeSourceImpl implements SingularAttributeSource {
return false; return false;
} }
@Override
public boolean areValuesIncludedInInsertByDefault() {
return true;
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return true;
}
@Override
public boolean areValuesNullableByDefault() {
return true;
}
@Override @Override
public List<RelationalValueSource> relationalValueSources() { public List<RelationalValueSource> relationalValueSources() {
return valueSources; return valueSources;

View File

@ -28,6 +28,7 @@ import java.util.Properties;
import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.HibernateTypeDescriptor; import org.hibernate.metamodel.binding.HibernateTypeDescriptor;
import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Datatype; import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.relational.SimpleValue;
@ -135,7 +136,8 @@ class AttributeTypeResolver {
// todo : this can be made a lot smarter, but for now this will suffice. currently we only handle single value bindings // 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 ( SingularAttribute.class.isInstance( attributeBinding.getAttribute() ) ) {
final Value value = SingularAttributeBinding.class.cast( attributeBinding ).getValue();
if ( SimpleValue.class.isInstance( value ) ) { if ( SimpleValue.class.isInstance( value ) ) {
SimpleValue simpleValue = (SimpleValue) value; SimpleValue simpleValue = (SimpleValue) value;
if ( simpleValue.getDatatype() == null ) { if ( simpleValue.getDatatype() == null ) {
@ -149,5 +151,6 @@ class AttributeTypeResolver {
} }
} }
} }
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,8 +25,8 @@ package org.hibernate.persister.spi;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.Service; import org.hibernate.service.Service;
@ -80,5 +80,5 @@ public interface PersisterClassResolver extends Service {
* *
* @return The collection persister class to use * @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.mapping.PersistentClass;
import org.hibernate.metamodel.source.MetadataImplementor; import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.binding.EntityBinding; 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.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.Service; import org.hibernate.service.Service;
@ -122,7 +122,7 @@ public interface PersisterFactory extends Service {
*/ */
public CollectionPersister createCollectionPersister( public CollectionPersister createCollectionPersister(
MetadataImplementor metadata, MetadataImplementor metadata,
PluralAttributeBinding model, AbstractPluralAttributeBinding model,
CollectionRegionAccessStrategy cacheAccessStrategy, CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException; SessionFactoryImplementor factory) throws HibernateException;

View File

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

View File

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

View File

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

View File

@ -60,7 +60,7 @@ public class SimpleValueBindingTests extends BaseUnitTestCase {
entityBinding.setBaseTable( table ); entityBinding.setBaseTable( table );
SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" ); SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute ); SimpleSingularAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute );
attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( "long" ); attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( "long" );
assertSame( idAttribute, attributeBinding.getAttribute() ); 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.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.domain.NonEntity; import org.hibernate.metamodel.domain.NonEntity;
import org.hibernate.metamodel.relational.Column; import org.hibernate.metamodel.relational.Column;
import org.hibernate.testing.FailureExpected; import org.hibernate.testing.FailureExpected;
@ -53,7 +54,7 @@ public class MappedSuperclassTests extends BaseAnnotationBindingTestCase {
// @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class }) // @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class })
public void testSimpleAttributeOverrideInMappedSuperclass() { public void testSimpleAttributeOverrideInMappedSuperclass() {
EntityBinding binding = getEntityBinding( MyEntity.class ); 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 ); assertNotNull( "the name attribute should be bound to MyEntity", nameBinding );
Column column = (Column) nameBinding.getValue(); Column column = (Column) nameBinding.getValue();
@ -64,7 +65,7 @@ public class MappedSuperclassTests extends BaseAnnotationBindingTestCase {
// @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class }) // @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class })
public void testLastAttributeOverrideWins() { public void testLastAttributeOverrideWins() {
EntityBinding binding = getEntityBinding( MyEntity.class ); 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 ); assertNotNull( "the foo attribute should be bound to MyEntity", fooBinding );
Column column = (Column) fooBinding.getValue(); Column column = (Column) fooBinding.getValue();

View File

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

View File

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