HHH-6447 - Develop shared binding creation approach

This commit is contained in:
Steve Ebersole 2011-07-19 17:57:34 -05:00
parent ab3d89ae51
commit 4968ad11fb
22 changed files with 68 additions and 1720 deletions

View File

@ -52,7 +52,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
private final EntityBinding entityBinding;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final Set<EntityReferencingAttributeBinding> entityReferencingAttributeBindings = new HashSet<EntityReferencingAttributeBinding>();
private final Set<SingularAssociationAttributeBinding> entityReferencingAttributeBindings = new HashSet<SingularAssociationAttributeBinding>();
private Attribute attribute;
private Value value;
@ -258,11 +258,11 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
this.isLazy = isLazy;
}
public void addEntityReferencingAttributeBinding(EntityReferencingAttributeBinding referencingAttributeBinding) {
public void addEntityReferencingAttributeBinding(SingularAssociationAttributeBinding referencingAttributeBinding) {
entityReferencingAttributeBindings.add( referencingAttributeBinding );
}
public Set<EntityReferencingAttributeBinding> getEntityReferencingAttributeBindings() {
public Set<SingularAssociationAttributeBinding> getEntityReferencingAttributeBindings() {
return Collections.unmodifiableSet( entityReferencingAttributeBindings );
}

View File

@ -21,35 +21,27 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.source.hbm.state.relational;
package org.hibernate.metamodel.binding;
import org.hibernate.metamodel.source.BindingContext;
import org.hibernate.metamodel.relational.state.ManyToOneRelationalState;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement;
import org.hibernate.engine.spi.CascadeStyle;
/**
* @author Gail Badner
* Contract describing a binding for attributes which model associations.
*
* @author Steve Ebersole
*/
public class HbmManyToOneRelationalStateContainer extends HbmSimpleValueRelationalStateContainer
implements ManyToOneRelationalState {
public interface AssociationAttributeBinding extends AttributeBinding {
/**
* Obtain the cascade styles in effect for this association.
*
* @return THe cascade styles.
*/
public Iterable<CascadeStyle> getCascadeStyles();
private final boolean isLogicalOneToOne;
private final String foreignKeyName;
public HbmManyToOneRelationalStateContainer(
BindingContext bindingContext,
boolean autoColumnCreation,
XMLManyToOneElement manyToOne ) {
super( bindingContext, autoColumnCreation, manyToOne );
this.isLogicalOneToOne = manyToOne.isUnique();
this.foreignKeyName = manyToOne.getForeignKey();
}
public boolean isLogicalOneToOne() {
return isLogicalOneToOne;
}
public String getForeignKeyName() {
return foreignKeyName;
}
/**
* Set the cascade styles in effect for this association.
*
* @param cascadeStyles The cascade styles.
*/
public void setCascadeStyles(Iterable<CascadeStyle> cascadeStyles);
}

View File

@ -110,9 +110,9 @@ public interface AttributeBinding {
public boolean isLazy();
public void addEntityReferencingAttributeBinding(EntityReferencingAttributeBinding attributeBinding);
public void addEntityReferencingAttributeBinding(SingularAssociationAttributeBinding attributeBinding);
public Set<EntityReferencingAttributeBinding> getEntityReferencingAttributeBindings();
public Set<SingularAssociationAttributeBinding> getEntityReferencingAttributeBindings();
public void validate();
}

View File

@ -68,8 +68,9 @@ public class EntityBinding {
private SimpleAttributeBinding versionBinding;
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
private Set<FilterDefinition> filterDefinitions = new HashSet<FilterDefinition>();
private Set<EntityReferencingAttributeBinding> entityReferencingAttributeBindings = new HashSet<EntityReferencingAttributeBinding>();
private Set<FilterDefinition> filterDefinitions = new HashSet<FilterDefinition>( );
private Set<SingularAssociationAttributeBinding> entityReferencingAttributeBindings = new HashSet<SingularAssociationAttributeBinding>();
private Caching caching;
@ -98,59 +99,6 @@ public class EntityBinding {
private Set<String> synchronizedTableNames = new HashSet<String>();
// public EntityBinding initialize(BindingContext bindingContext, EntityDescriptor state) {
// // todo : Entity will need both entityName and className to be effective
// this.entity = new Entity( state.getEntityName(), state.getSuperType(), bindingContext.makeJavaType( state.getClassName() ) );
//
// this.isRoot = state.isRoot();
// this.entityInheritanceType = state.getEntityInheritanceType();
//
// this.entityMode = state.getEntityMode();
// this.jpaEntityName = state.getJpaEntityName();
//
// // todo : handle the entity-persister-resolver stuff
// this.customEntityPersisterClass = state.getCustomEntityPersisterClass();
// this.customEntityTuplizerClass = state.getCustomEntityTuplizerClass();
//
// this.caching = state.getCaching();
// this.metaAttributeContext = state.getMetaAttributeContext();
//
// if ( entityMode == EntityMode.POJO ) {
// if ( state.getProxyInterfaceName() != null ) {
// this.proxyInterfaceType = bindingContext.makeJavaType( state.getProxyInterfaceName() );
// this.lazy = true;
// }
// else if ( state.isLazy() ) {
// this.proxyInterfaceType = entity.getJavaType();
// this.lazy = true;
// }
// }
// else {
// this.proxyInterfaceType = new JavaType( Map.class );
// this.lazy = state.isLazy();
// }
//
// this.mutable = state.isMutable();
// this.explicitPolymorphism = state.isExplicitPolymorphism();
// this.whereFilter = state.getWhereFilter();
// this.rowId = state.getRowId();
// this.dynamicUpdate = state.isDynamicUpdate();
// this.dynamicInsert = state.isDynamicInsert();
// this.batchSize = state.getBatchSize();
// this.selectBeforeUpdate = state.isSelectBeforeUpdate();
// this.optimisticLockMode = state.getOptimisticLockMode();
// this.isAbstract = state.isAbstract();
// this.customInsert = state.getCustomInsert();
// this.customUpdate = state.getCustomUpdate();
// this.customDelete = state.getCustomDelete();
// if ( state.getSynchronizedTableNames() != null ) {
// for ( String synchronizedTableName : state.getSynchronizedTableNames() ) {
// addSynchronizedTable( synchronizedTableName );
// }
// }
// return this;
// }
public Entity getEntity() {
return entity;
}
@ -249,7 +197,7 @@ public class EntityBinding {
filterDefinitions.add( filterDefinition );
}
public Iterable<EntityReferencingAttributeBinding> getEntityReferencingAttributeBindings() {
public Iterable<SingularAssociationAttributeBinding> getEntityReferencingAttributeBindings() {
return entityReferencingAttributeBindings;
}
@ -298,7 +246,7 @@ public class EntityBinding {
return binding;
}
private void registerAttributeBinding(String name, EntityReferencingAttributeBinding attributeBinding) {
private void registerAttributeBinding(String name, SingularAssociationAttributeBinding attributeBinding) {
entityReferencingAttributeBindings.add( attributeBinding );
registerAttributeBinding( name, (AttributeBinding) attributeBinding );
}

View File

@ -39,7 +39,7 @@ import org.hibernate.metamodel.relational.state.ManyToOneRelationalState;
* @author Gail Badner
* @author Steve Ebersole
*/
public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements EntityReferencingAttributeBinding {
public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements SingularAssociationAttributeBinding {
private String referencedAttributeName;
private String referencedEntityName;

View File

@ -31,9 +31,6 @@ import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState;
import org.hibernate.metamodel.domain.SingularAttribute;
@ -45,7 +42,7 @@ import org.hibernate.metamodel.relational.state.ValueRelationalState;
*
* @author Steve Ebersole
*/
public class SimpleAttributeBinding extends AbstractAttributeBinding implements KeyValueBinding {
public class SimpleAttributeBinding extends AbstractAttributeBinding implements SingularAttributeBinding, KeyValueBinding {
private boolean insertable;
private boolean updatable;
private PropertyGeneration generation;

View File

@ -23,26 +23,38 @@
*/
package org.hibernate.metamodel.binding;
import org.hibernate.engine.spi.CascadeStyle;
/**
* TODO : javadoc
* Contract describing the attribute binding for singular associations ({@code many-to-one}, {@code one-to-one}).
*
* @author Gail Badner
* @author Steve Ebersole
*/
public interface EntityReferencingAttributeBinding extends AttributeBinding {
public interface SingularAssociationAttributeBinding extends SingularAttributeBinding, AssociationAttributeBinding {
/**
* Is this association based on a property reference (non PK column(s) as target of FK)?
* <p/>
* Convenience form of checking {@link #getReferencedAttributeName()} for {@code null}.
*
* @return
*/
public boolean isPropertyReference();
/**
* Obtain the name of the referenced entity.
*
* @return The referenced entity name
*/
public String getReferencedEntityName();
/**
* Set the name of the
* @param referencedEntityName
*/
public void setReferencedEntityName(String referencedEntityName);
public String getReferencedAttributeName();
public void setReferencedAttributeName(String referencedAttributeName);
public Iterable<CascadeStyle> getCascadeStyles();
public void setCascadeStyles(Iterable<CascadeStyle> cascadeStyles);
// "resolvable"
public void resolveReference(AttributeBinding attributeBinding);

View File

@ -21,21 +21,10 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.source.hbm.state.relational;
import org.hibernate.metamodel.relational.state.DerivedValueRelationalState;
package org.hibernate.metamodel.binding;
/**
* @author Gail Badner
* @author Steve Ebersole
*/
public class HbmDerivedValueRelationalState implements DerivedValueRelationalState {
private final String formula;
public HbmDerivedValueRelationalState(String formula) {
this.formula = formula.trim();
}
public String getFormula() {
return formula;
}
public interface SingularAttributeBinding extends AttributeBinding {
}

View File

@ -36,5 +36,5 @@ public interface AssociationAttributeSource extends AttributeSource {
*
* @return The cascade styles.
*/
public Iterable<CascadeStyle> getCascadeStyle();
public Iterable<CascadeStyle> getCascadeStyles();
}

View File

@ -371,7 +371,7 @@ public class Binder {
else if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) {
attributeBinding = entityBinding.makeManyToOneAttributeBinding( attribute );
resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding );
resolveToOneReferenceInformation( (ToOneAttributeSource) attributeSource, (ManyToOneAttributeBinding) attributeBinding );
resolveToOneInformation( (ToOneAttributeSource) attributeSource, (ManyToOneAttributeBinding) attributeBinding );
}
else {
throw new NotYetImplementedException();
@ -463,13 +463,15 @@ public class Binder {
}
}
private void resolveToOneReferenceInformation(ToOneAttributeSource attributeSource, ManyToOneAttributeBinding attributeBinding) {
private void resolveToOneInformation(ToOneAttributeSource attributeSource, ManyToOneAttributeBinding attributeBinding) {
final String referencedEntityName = attributeSource.getReferencedEntityName() != null
? attributeSource.getReferencedEntityName()
: attributeBinding.getAttribute().getSingularAttributeType().getClassName();
attributeBinding.setReferencedEntityName( referencedEntityName );
// todo : we should consider basing references on columns instead of property-ref, which would require a resolution (later) of property-ref to column names
attributeBinding.setReferencedAttributeName( attributeSource.getReferencedEntityAttributeName() );
attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() );
}
private MetaAttributeContext buildMetaAttributeContext(EntitySource entitySource) {

View File

@ -226,7 +226,7 @@ public class Helper {
if ( StringHelper.isEmpty( cascades ) ) {
cascades = bindingContext.getMappingDefaults().getCascadeStyle();
}
for ( String cascade : StringHelper.split( cascades, "," ) ) {
for ( String cascade : StringHelper.split( ",", cascades ) ) {
cascadeStyles.add( CascadeStyle.getCascadeStyle( cascade ) );
}
return cascadeStyles;

View File

@ -110,7 +110,7 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
}
@Override
public Iterable<CascadeStyle> getCascadeStyle() {
public Iterable<CascadeStyle> getCascadeStyles() {
return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext );
}

View File

@ -1,158 +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.source.hbm.state.binding;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.hibernate.MappingException;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.BindingContext;
import org.hibernate.metamodel.source.MappingDefaults;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.hbm.Helper;
import org.hibernate.metamodel.binding.CascadeType;
import org.hibernate.metamodel.binding.state.AttributeBindingState;
/**
* @author Gail Badner
*/
public abstract class AbstractHbmAttributeBindingState implements AttributeBindingState {
private final String ownerClassName;
private final String attributeName;
private final BindingContext bindingContext;
private final String nodeName;
private final String accessorName;
private final boolean isOptimisticLockable;
private final MetaAttributeContext metaAttributeContext;
public AbstractHbmAttributeBindingState(
String ownerClassName,
String attributeName,
BindingContext bindingContext,
String nodeName,
MetaAttributeContext metaAttributeContext,
String accessorName,
boolean isOptimisticLockable) {
if ( attributeName == null ) {
throw new MappingException(
"Attribute name cannot be null."
);
}
this.ownerClassName = ownerClassName;
this.attributeName = attributeName;
this.bindingContext = bindingContext;
this.nodeName = nodeName;
this.metaAttributeContext = metaAttributeContext;
this.accessorName = accessorName;
this.isOptimisticLockable = isOptimisticLockable;
}
// TODO: really don't like this here...
protected String getOwnerClassName() {
return ownerClassName;
}
protected Set<CascadeType> determineCascadeTypes(String cascade) {
String commaSeparatedCascades = Helper.getStringValue(
cascade,
getBindingContext().getMappingDefaults()
.getCascadeStyle()
);
Set<String> cascades = Helper.getStringValueTokens( commaSeparatedCascades, "," );
Set<CascadeType> cascadeTypes = new HashSet<CascadeType>( cascades.size() );
for ( String s : cascades ) {
CascadeType cascadeType = CascadeType.getCascadeType( s );
if ( cascadeType == null ) {
throw new MappingException( "Invalid cascading option " + s );
}
cascadeTypes.add( cascadeType );
}
return cascadeTypes;
}
protected final String getTypeNameByReflection() {
Class ownerClass = bindingContext.locateClassByName( ownerClassName );
return ReflectHelper.reflectedPropertyClass( ownerClass, attributeName ).getName();
}
public String getAttributeName() {
return attributeName;
}
public BindingContext getBindingContext() {
return bindingContext;
}
@Deprecated
protected final MappingDefaults getDefaults() {
return getBindingContext().getMappingDefaults();
}
@Override
public final String getPropertyAccessorName() {
return accessorName;
}
@Override
public final boolean isAlternateUniqueKey() {
//TODO: implement
return false;
}
@Override
public final boolean isOptimisticLockable() {
return isOptimisticLockable;
}
@Override
public final String getNodeName() {
return nodeName == null ? getAttributeName() : nodeName;
}
@Override
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}
public PropertyGeneration getPropertyGeneration() {
return PropertyGeneration.NEVER;
}
public boolean isKeyCascadeDeleteEnabled() {
return false;
}
public String getUnsavedValue() {
//TODO: implement
return null;
}
public Map<String, String> getExplicitHibernateTypeParameters() {
return null;
}
}

View File

@ -1,106 +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.source.hbm.state.binding;
import java.util.Set;
import org.hibernate.metamodel.binding.CascadeType;
import org.hibernate.metamodel.binding.state.DiscriminatorBindingState;
import org.hibernate.metamodel.source.BindingContext;
import org.hibernate.metamodel.source.hbm.Helper;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLDiscriminator;
/**
* @author Gail Badner
*/
public class HbmDiscriminatorBindingState
extends AbstractHbmAttributeBindingState
implements DiscriminatorBindingState {
private final String discriminatorValue;
private final boolean isForced;
private final boolean isInserted;
private final String explicitHibernateTypeName;
public HbmDiscriminatorBindingState(
String entityName,
String ownerClassName,
BindingContext bindingContext,
XMLHibernateMapping.XMLClass xmlEntityClazz) {
super(
ownerClassName,
bindingContext.getMappingDefaults().getDiscriminatorColumnName(),
bindingContext,
null,
null,
null,
true
);
XMLDiscriminator discriminator = xmlEntityClazz.getDiscriminator();
this.discriminatorValue = Helper.getStringValue(
xmlEntityClazz.getDiscriminatorValue(), entityName
);
this.isForced = xmlEntityClazz.getDiscriminator().isForce();
this.isInserted = discriminator.isInsert();
this.explicitHibernateTypeName = discriminator.getType() == null ? "string" : discriminator.getType();
}
public Set<CascadeType> getCascadeTypes() {
return null;
}
protected boolean isEmbedded() {
return false;
}
public String getExplicitHibernateTypeName() {
return explicitHibernateTypeName;
}
@Override
public String getJavaTypeName() {
return null;
}
@Override
public boolean isLazy() {
return false;
}
@Override
public boolean isInserted() {
return isInserted;
}
@Override
public String getDiscriminatorValue() {
return discriminatorValue;
}
@Override
public boolean isForced() {
return isForced;
}
}

View File

@ -1,188 +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.source.hbm.state.binding;
import java.util.Set;
import org.hibernate.FetchMode;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.metamodel.source.BindingContext;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.hbm.Helper;
import org.hibernate.metamodel.binding.CascadeType;
import org.hibernate.metamodel.binding.state.ManyToOneAttributeBindingState;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement;
/**
* @author Gail Badner
*/
public class HbmManyToOneAttributeBindingState
extends AbstractHbmAttributeBindingState
implements ManyToOneAttributeBindingState {
private final FetchMode fetchMode;
private final boolean isUnwrapProxy;
private final boolean isLazy;
private final Set<CascadeType> cascadeTypes;
private final boolean isEmbedded;
private final String referencedPropertyName;
private final String referencedEntityName;
private final boolean ignoreNotFound;
private final boolean isInsertable;
private final boolean isUpdateable;
public HbmManyToOneAttributeBindingState(
String ownerClassName,
BindingContext bindingContext,
MetaAttributeContext parentMetaAttributeContext,
XMLManyToOneElement manyToOne) {
super(
ownerClassName,
manyToOne.getName(),
bindingContext,
manyToOne.getNode(),
Helper.extractMetaAttributeContext( manyToOne.getMeta(), parentMetaAttributeContext ),
Helper.getPropertyAccessorName(
manyToOne.getAccess(),
manyToOne.isEmbedXml(),
bindingContext.getMappingDefaults().getPropertyAccessorName()
),
manyToOne.isOptimisticLock()
);
fetchMode = getFetchMode( manyToOne );
isUnwrapProxy = manyToOne.getLazy() != null && "no-proxy".equals( manyToOne.getLazy().value() );
//TODO: better to degrade to lazy="false" if uninstrumented
isLazy = manyToOne.getLazy() == null ||
isUnwrapProxy ||
"proxy".equals( manyToOne.getLazy().value() );
cascadeTypes = determineCascadeTypes( manyToOne.getCascade() );
isEmbedded = manyToOne.isEmbedXml();
referencedEntityName = getReferencedEntityName( ownerClassName, manyToOne, bindingContext );
referencedPropertyName = manyToOne.getPropertyRef();
ignoreNotFound = "ignore".equals( manyToOne.getNotFound().value() );
isInsertable = manyToOne.isInsert();
isUpdateable = manyToOne.isUpdate();
}
// TODO: is this needed???
protected boolean isEmbedded() {
return isEmbedded;
}
private static String getReferencedEntityName(
String ownerClassName,
XMLManyToOneElement manyToOne,
BindingContext bindingContext) {
String referencedEntityName;
if ( manyToOne.getEntityName() != null ) {
referencedEntityName = manyToOne.getEntityName();
}
else if ( manyToOne.getClazz() != null ) {
referencedEntityName = Helper.qualifyIfNeeded(
manyToOne.getClazz(), bindingContext.getMappingDefaults().getPackageName()
);
}
else {
Class ownerClazz = Helper.classForName( ownerClassName, bindingContext.getServiceRegistry() );
referencedEntityName = ReflectHelper.reflectedPropertyClass( ownerClazz, manyToOne.getName() ).getName();
}
return referencedEntityName;
}
// same as for plural attributes...
private static FetchMode getFetchMode(XMLManyToOneElement manyToOne) {
FetchMode fetchMode;
if ( manyToOne.getFetch() != null ) {
fetchMode = "join".equals( manyToOne.getFetch().value() ) ? FetchMode.JOIN : FetchMode.SELECT;
}
else {
String jfNodeValue = ( manyToOne.getOuterJoin() == null ? "auto" : manyToOne.getOuterJoin().value() );
if ( "auto".equals( jfNodeValue ) ) {
fetchMode = FetchMode.DEFAULT;
}
else if ( "true".equals( jfNodeValue ) ) {
fetchMode = FetchMode.JOIN;
}
else {
fetchMode = FetchMode.SELECT;
}
}
return fetchMode;
}
public String getExplicitHibernateTypeName() {
return null;
}
@Override
public String getJavaTypeName() {
return referencedEntityName;
}
public FetchMode getFetchMode() {
return fetchMode;
}
public boolean isLazy() {
return isLazy;
}
public boolean isUnwrapProxy() {
return isUnwrapProxy;
}
public String getReferencedAttributeName() {
return referencedPropertyName;
}
public String getReferencedEntityName() {
return referencedEntityName;
}
public Set<CascadeType> getCascadeTypes() {
return cascadeTypes;
}
public boolean ignoreNotFound() {
return ignoreNotFound;
}
public boolean isInsertable() {
return isInsertable;
}
public boolean isUpdatable() {
return isUpdateable;
}
public boolean isKeyCascadeDeleteEnabled() {
//TODO: implement
return false;
}
public String getUnsavedValue() {
//TODO: implement
return null;
}
}

View File

@ -1,291 +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.source.hbm.state.binding;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.FetchMode;
import org.hibernate.metamodel.binding.CascadeType;
import org.hibernate.metamodel.binding.CustomSQL;
import org.hibernate.metamodel.binding.state.PluralAttributeBindingState;
import org.hibernate.metamodel.source.BindingContext;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.hbm.Helper;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLBagElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSqlDeleteAllElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSqlDeleteElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSqlInsertElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSqlUpdateElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSynchronizeElement;
/**
* @author Gail Badner
*/
public class HbmPluralAttributeBindingState extends AbstractHbmAttributeBindingState
implements PluralAttributeBindingState {
private final XMLBagElement collection;
private final Class collectionPersisterClass;
private final Set<CascadeType> cascadeTypes;
private final String explicitHibernateCollectionTypeName;
private final Class javaType;
public HbmPluralAttributeBindingState(
String ownerClassName,
BindingContext bindingContext,
MetaAttributeContext parentMetaAttributeContext,
XMLBagElement collection) {
super(
ownerClassName,
collection.getName(),
bindingContext,
collection.getNode(),
Helper.extractMetaAttributeContext( collection.getMeta(), parentMetaAttributeContext ),
Helper.getPropertyAccessorName(
collection.getAccess(),
collection.isEmbedXml(),
bindingContext.getMappingDefaults().getPropertyAccessorName()
),
collection.isOptimisticLock()
);
this.collection = collection;
this.collectionPersisterClass = Helper.classForName(
collection.getPersister(), getBindingContext().getServiceRegistry()
);
this.cascadeTypes = determineCascadeTypes( collection.getCascade() );
//Attribute typeNode = collectionElement.attribute( "collection-type" );
//if ( typeNode != null ) {
// TODO: implement when typedef binding is implemented
/*
String typeName = typeNode.getValue();
TypeDef typeDef = mappings.getTypeDef( typeName );
if ( typeDef != null ) {
collectionBinding.setTypeName( typeDef.getTypeClass() );
collectionBinding.setTypeParameters( typeDef.getParameters() );
}
else {
collectionBinding.setTypeName( typeName );
}
*/
//}
this.explicitHibernateCollectionTypeName = collection.getCollectionType();
this.javaType = java.util.Collection.class;
}
public FetchMode getFetchMode() {
FetchMode fetchMode;
if ( collection.getFetch() != null ) {
fetchMode = "join".equals( collection.getFetch().value() ) ? FetchMode.JOIN : FetchMode.SELECT;
}
else {
String jfNodeValue = ( collection.getOuterJoin().value() == null ? "auto" : collection.getOuterJoin()
.value() );
if ( "auto".equals( jfNodeValue ) ) {
fetchMode = FetchMode.DEFAULT;
}
else if ( "true".equals( jfNodeValue ) ) {
fetchMode = FetchMode.JOIN;
}
else {
fetchMode = FetchMode.SELECT;
}
}
return fetchMode;
}
public boolean isLazy() {
return isExtraLazy() ||
Helper.getBooleanValue(
collection.getLazy().value(), getBindingContext().getMappingDefaults().areAssociationsLazy()
);
}
public boolean isExtraLazy() {
return ( "extra".equals( collection.getLazy().value() ) );
}
public String getElementTypeName() {
return collection.getElement().getTypeAttribute();
}
public String getElementNodeName() {
return collection.getElement().getNode();
}
public boolean isInverse() {
return collection.isInverse();
}
public boolean isMutable() {
return collection.isMutable();
}
public boolean isSubselectLoadable() {
return "subselect".equals( collection.getFetch().value() );
}
public String getCacheConcurrencyStrategy() {
return collection.getCache() == null ?
null :
collection.getCache().getUsage();
}
public String getCacheRegionName() {
return collection.getCache() == null ?
null :
collection.getCache().getRegion();
}
public String getOrderBy() {
return collection.getOrderBy();
}
public String getWhere() {
return collection.getWhere();
}
public String getReferencedPropertyName() {
return collection.getKey().getPropertyRef();
}
public boolean isSorted() {
// SORT
// unsorted, natural, comparator.class.name
return ( !"unsorted".equals( getSortString() ) );
}
public Comparator getComparator() {
return null;
}
public String getComparatorClassName() {
String sortString = getSortString();
return (
isSorted() && !"natural".equals( sortString ) ?
sortString :
null
);
}
private String getSortString() {
//TODO: Bag does not define getSort(); update this when there is a Collection subtype
// collection.getSort() == null ? "unsorted" : collection.getSort();
return "unsorted";
}
public boolean isOrphanDelete() {
// ORPHAN DELETE (used for programmer error detection)
return true;
//return ( getCascade().indexOf( "delete-orphan" ) >= 0 );
}
public int getBatchSize() {
return Helper.getIntValue( collection.getBatchSize(), 0 );
}
@Override
public boolean isEmbedded() {
return collection.isEmbedXml();
}
public boolean isOptimisticLocked() {
return collection.isOptimisticLock();
}
public Class getCollectionPersisterClass() {
return collectionPersisterClass;
}
public java.util.Map getFilters() {
// TODO: IMPLEMENT
//Iterator iter = collectionElement.elementIterator( "filter" );
//while ( iter.hasNext() ) {
// final Element filter = (Element) iter.next();
// parseFilter( filter, collectionElement, collectionBinding );
//}
return new HashMap();
}
public java.util.Set getSynchronizedTables() {
java.util.Set<String> synchronizedTables = new HashSet<String>();
for ( XMLSynchronizeElement sync : collection.getSynchronize() ) {
synchronizedTables.add( sync.getTable() );
}
return synchronizedTables;
}
public CustomSQL getCustomSQLInsert() {
XMLSqlInsertElement sqlInsert = collection.getSqlInsert();
return Helper.buildCustomSql( sqlInsert );
}
public CustomSQL getCustomSQLUpdate() {
XMLSqlUpdateElement sqlUpdate = collection.getSqlUpdate();
return Helper.buildCustomSql( sqlUpdate );
}
public CustomSQL getCustomSQLDelete() {
XMLSqlDeleteElement sqlDelete = collection.getSqlDelete();
return Helper.buildCustomSql( sqlDelete );
}
public CustomSQL getCustomSQLDeleteAll() {
XMLSqlDeleteAllElement sqlDeleteAll = collection.getSqlDeleteAll();
return Helper.buildCustomSql( sqlDeleteAll );
}
public String getLoaderName() {
return collection.getLoader() == null ?
null :
collection.getLoader().getQueryRef();
}
public Set<CascadeType> getCascadeTypes() {
return cascadeTypes;
}
public boolean isKeyCascadeDeleteEnabled() {
//TODO: implement
return false;
}
public String getUnsavedValue() {
//TODO: implement
return null;
}
public String getExplicitHibernateTypeName() {
return explicitHibernateCollectionTypeName;
}
@Override
public String getJavaTypeName() {
return javaType.getName();
}
}

View File

@ -1,340 +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.source.hbm.state.binding;
import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.hibernate.MappingException;
import org.hibernate.internal.util.beans.BeanInfoHelper;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.BindingContext;
import org.hibernate.metamodel.source.MappingDefaults;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.hbm.Helper;
import org.hibernate.metamodel.binding.CascadeType;
import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLId;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLTimestamp;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLVersion;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLParamElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLPropertyElement;
/**
* @author Gail Badner
*/
public class HbmSimpleAttributeBindingState extends AbstractHbmAttributeBindingState
implements SimpleAttributeBindingState {
private final String explicitHibernateTypeName;
private final Map<String, String> explicitHibernateTypeParameters = new HashMap<String, String>();
private final boolean isLazy;
private final PropertyGeneration propertyGeneration;
private final boolean isInsertable;
private final boolean isUpdatable;
public HbmSimpleAttributeBindingState(
String ownerClassName,
BindingContext bindingContext,
MetaAttributeContext parentMetaAttributeContext,
XMLId id) {
super(
ownerClassName,
id.getName() != null ? id.getName() : bindingContext.getMappingDefaults().getIdColumnName(),
bindingContext,
id.getNode(),
Helper.extractMetaAttributeContext( id.getMeta(), parentMetaAttributeContext ),
Helper.getPropertyAccessorName(
id.getAccess(),
false,
bindingContext.getMappingDefaults().getPropertyAccessorName()
),
true
);
this.isLazy = false;
if ( id.getTypeAttribute() != null ) {
explicitHibernateTypeName = maybeConvertToTypeDefName( id.getTypeAttribute(), bindingContext.getMappingDefaults() );
}
else if ( id.getType() != null ) {
explicitHibernateTypeName = maybeConvertToTypeDefName( id.getType().getName(), bindingContext.getMappingDefaults() );
}
else {
explicitHibernateTypeName = getTypeNameByReflection();
}
// TODO: how should these be set???
this.propertyGeneration = PropertyGeneration.parse( null );
this.isInsertable = true;
this.isUpdatable = false;
}
private static String maybeConvertToTypeDefName(String typeName, MappingDefaults defaults) {
String actualTypeName = typeName;
if ( typeName != null ) {
// TODO: tweak for typedef...
}
else {
}
return actualTypeName;
}
public HbmSimpleAttributeBindingState(
String ownerClassName,
BindingContext bindingContext,
MetaAttributeContext parentMetaAttributeContext,
XMLVersion version) {
super(
ownerClassName,
version.getName(),
bindingContext,
version.getNode(),
Helper.extractMetaAttributeContext( version.getMeta(), parentMetaAttributeContext ),
Helper.getPropertyAccessorName(
version.getAccess(),
false,
bindingContext.getMappingDefaults().getPropertyAccessorName()
),
true
);
this.explicitHibernateTypeName = version.getType() == null ? "integer" : version.getType();
this.isLazy = false;
// for version properties marked as being generated, make sure they are "always"
// generated; aka, "insert" is invalid; this is dis-allowed by the DTD,
// but just to make sure.
this.propertyGeneration = PropertyGeneration.parse( version.getGenerated().value() );
if ( propertyGeneration == PropertyGeneration.INSERT ) {
throw new MappingException( "'generated' attribute cannot be 'insert' for versioning property" );
}
this.isInsertable = Helper.getBooleanValue( version.isInsert(), true );
this.isUpdatable = true;
}
public HbmSimpleAttributeBindingState(
String ownerClassName,
BindingContext bindingContext,
MetaAttributeContext parentMetaAttributeContext,
XMLTimestamp timestamp) {
super(
ownerClassName,
timestamp.getName(),
bindingContext,
timestamp.getNode(),
Helper.extractMetaAttributeContext( timestamp.getMeta(), parentMetaAttributeContext ),
Helper.getPropertyAccessorName(
timestamp.getAccess(),
false,
bindingContext.getMappingDefaults().getPropertyAccessorName()
),
true
);
// Timestamp.getType() is not defined
this.explicitHibernateTypeName = "db".equals( timestamp.getSource() ) ? "dbtimestamp" : "timestamp";
this.isLazy = false;
// for version properties marked as being generated, make sure they are "always"
// generated; aka, "insert" is invalid; this is dis-allowed by the DTD,
// but just to make sure.
this.propertyGeneration = PropertyGeneration.parse( timestamp.getGenerated().value() );
if ( propertyGeneration == PropertyGeneration.INSERT ) {
throw new MappingException( "'generated' attribute cannot be 'insert' for versioning property" );
}
this.isInsertable = true; //TODO: is this right????
this.isUpdatable = true;
}
public HbmSimpleAttributeBindingState(
String ownerClassName,
BindingContext bindingContext,
MetaAttributeContext parentMetaAttributeContext,
XMLPropertyElement property) {
super(
ownerClassName,
property.getName(),
bindingContext,
property.getNode(),
Helper.extractMetaAttributeContext( property.getMeta(), parentMetaAttributeContext ),
Helper.getPropertyAccessorName(
property.getAccess(),
false,
bindingContext.getMappingDefaults().getPropertyAccessorName()
),
property.isOptimisticLock()
);
this.isLazy = property.isLazy();
this.propertyGeneration = PropertyGeneration.parse( property.getGenerated() );
if ( propertyGeneration == PropertyGeneration.ALWAYS || propertyGeneration == PropertyGeneration.INSERT ) {
// generated properties can *never* be insertable.
if ( property.isInsert() != null && property.isInsert() ) {
// the user specifically supplied insert="true", which constitutes an illegal combo
throw new MappingException(
"cannot specify both insert=\"true\" and generated=\"" + propertyGeneration.getName() +
"\" for property: " +
property.getName()
);
}
isInsertable = false;
}
else {
isInsertable = Helper.getBooleanValue( property.isInsert(), true );
}
if ( propertyGeneration == PropertyGeneration.ALWAYS ) {
if ( property.isUpdate() != null && property.isUpdate() ) {
// the user specifically supplied update="true",
// which constitutes an illegal combo
throw new MappingException(
"cannot specify both update=\"true\" and generated=\"" + propertyGeneration.getName() +
"\" for property: " +
property.getName()
);
}
isUpdatable = false;
}
else {
isUpdatable = Helper.getBooleanValue( property.isUpdate(), true );
}
if ( property.getTypeAttribute() != null ) {
explicitHibernateTypeName = maybeConvertToTypeDefName( property.getTypeAttribute(), bindingContext.getMappingDefaults() );
}
else if ( property.getType() != null ) {
explicitHibernateTypeName = maybeConvertToTypeDefName( property.getType().getName(), bindingContext.getMappingDefaults() );
for ( XMLParamElement typeParameter : property.getType().getParam() ) {
//TODO: add parameters from typedef
explicitHibernateTypeParameters.put( typeParameter.getName(), typeParameter.getValue().trim() );
}
}
else {
explicitHibernateTypeName = getTypeNameByReflection();
}
// TODO: check for typedef first
/*
TypeDef typeDef = mappings.getTypeDef( typeName );
if ( typeDef != null ) {
typeName = typeDef.getTypeClass();
// parameters on the property mapping should
// override parameters in the typedef
Properties allParameters = new Properties();
allParameters.putAll( typeDef.getParameters() );
allParameters.putAll( parameters );
parameters = allParameters;
}
*/
}
protected boolean isEmbedded() {
return false;
}
private String javaType;
@Override
public String getJavaTypeName() {
if ( javaType == null ) {
javaType = tryToResolveAttributeJavaType();
}
return javaType;
}
private String tryToResolveAttributeJavaType() {
try {
Class ownerClass = getBindingContext().locateClassByName( super.getOwnerClassName() );
AttributeLocatorDelegate delegate = new AttributeLocatorDelegate( getAttributeName() );
BeanInfoHelper.visitBeanInfo( ownerClass, delegate );
return delegate.attributeTypeName;
}
catch (Exception ignore) {
}
return null;
}
private static class AttributeLocatorDelegate implements BeanInfoHelper.BeanInfoDelegate {
private final String attributeName;
private String attributeTypeName;
private AttributeLocatorDelegate(String attributeName) {
this.attributeName = attributeName;
}
@Override
public void processBeanInfo(BeanInfo beanInfo) throws Exception {
for ( PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors() ) {
if ( propertyDescriptor.getName().equals( attributeName ) ) {
attributeTypeName = propertyDescriptor.getPropertyType().getName();
break;
}
}
}
}
public String getExplicitHibernateTypeName() {
return explicitHibernateTypeName;
}
public Map<String, String> getExplicitHibernateTypeParameters() {
return explicitHibernateTypeParameters;
}
public boolean isLazy() {
return isLazy;
}
public PropertyGeneration getPropertyGeneration() {
return propertyGeneration;
}
public boolean isInsertable() {
return isInsertable;
}
public boolean isUpdatable() {
return isUpdatable;
}
public Set<CascadeType> getCascadeTypes() {
return null;
}
public boolean isKeyCascadeDeleteEnabled() {
//TODO: implement
return false;
}
public String getUnsavedValue() {
//TODO: implement
return null;
}
}

View File

@ -1,276 +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.source.hbm.state.relational;
import java.util.Set;
import org.hibernate.MappingException;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.metamodel.source.hbm.Helper;
import org.hibernate.metamodel.relational.Size;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLColumnElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLDiscriminator;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLId;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLTimestamp;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLVersion;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLPropertyElement;
import org.hibernate.metamodel.relational.state.ColumnRelationalState;
// TODO: remove duplication after Id, Discriminator, Version, Timestamp, and Property extend a common interface.
/**
* @author Gail Badner
*/
public class HbmColumnRelationalState implements ColumnRelationalState {
private final HbmSimpleValueRelationalStateContainer container;
private final String explicitColumnName;
private final Size size;
private final boolean isNullable;
private final boolean isUnique;
private final String checkCondition;
private final String defaultColumnValue;
private final String sqlType;
private final String customWrite;
private final String customRead;
private final String comment;
private final Set<String> uniqueKeys;
private final Set<String> indexes;
/* package-protected */
HbmColumnRelationalState(XMLColumnElement columnElement,
HbmSimpleValueRelationalStateContainer container) {
this.container = container;
this.explicitColumnName = columnElement.getName();
this.size = createSize( columnElement.getLength(), columnElement.getScale(), columnElement.getPrecision() );
this.isNullable = !Helper.getBooleanValue( columnElement.isNotNull(), true );
this.isUnique = Helper.getBooleanValue( columnElement.isUnique(), true );
this.checkCondition = columnElement.getCheck();
this.defaultColumnValue = columnElement.getDefault();
this.sqlType = columnElement.getSqlType();
this.customWrite = columnElement.getWrite();
if ( customWrite != null && !customWrite.matches( "[^?]*\\?[^?]*" ) ) {
throw new MappingException( "write expression must contain exactly one value placeholder ('?') character" );
}
this.customRead = columnElement.getRead();
this.comment = columnElement.getComment() == null ? null : columnElement.getComment().trim();
this.uniqueKeys = Helper.getStringValueTokens( columnElement.getUniqueKey(), ", " );
this.uniqueKeys.addAll( container.getPropertyUniqueKeys() );
this.indexes = Helper.getStringValueTokens( columnElement.getIndex(), ", " );
this.indexes.addAll( container.getPropertyIndexes() );
}
HbmColumnRelationalState(XMLPropertyElement property,
HbmSimpleValueRelationalStateContainer container) {
this.container = container;
this.explicitColumnName = property.getName();
this.size = createSize( property.getLength(), property.getScale(), property.getPrecision() );
this.isUnique = Helper.getBooleanValue( property.isUnique(), true );
this.isNullable = !Helper.getBooleanValue( property.isNotNull(), true );
this.checkCondition = null;
this.defaultColumnValue = null;
this.sqlType = null;
this.customWrite = null;
this.customRead = null;
this.comment = null;
this.uniqueKeys = Helper.getStringValueTokens( property.getUniqueKey(), ", " );
this.uniqueKeys.addAll( container.getPropertyUniqueKeys() );
this.indexes = Helper.getStringValueTokens( property.getIndex(), ", " );
this.indexes.addAll( container.getPropertyIndexes() );
}
HbmColumnRelationalState(XMLManyToOneElement manyToOne,
HbmSimpleValueRelationalStateContainer container) {
this.container = container;
this.explicitColumnName = manyToOne.getName();
this.size = new Size();
this.isNullable = !Helper.getBooleanValue( manyToOne.isNotNull(), false );
this.isUnique = manyToOne.isUnique();
this.checkCondition = null;
this.defaultColumnValue = null;
this.sqlType = null;
this.customWrite = null;
this.customRead = null;
this.comment = null;
this.uniqueKeys = Helper.getStringValueTokens( manyToOne.getUniqueKey(), ", " );
this.uniqueKeys.addAll( container.getPropertyUniqueKeys() );
this.indexes = Helper.getStringValueTokens( manyToOne.getIndex(), ", " );
this.indexes.addAll( container.getPropertyIndexes() );
}
HbmColumnRelationalState(XMLId id,
HbmSimpleValueRelationalStateContainer container) {
if ( id.getColumn() != null && !id.getColumn().isEmpty() ) {
throw new IllegalArgumentException( "This method should not be called with non-empty id.getColumnElement()" );
}
this.container = container;
this.explicitColumnName = id.getName();
this.size = createSize( id.getLength(), null, null );
this.isNullable = false;
this.isUnique = true;
this.checkCondition = null;
this.defaultColumnValue = null;
this.sqlType = null;
this.customWrite = null;
this.customRead = null;
this.comment = null;
this.uniqueKeys = container.getPropertyUniqueKeys();
this.indexes = container.getPropertyIndexes();
}
HbmColumnRelationalState(XMLDiscriminator discriminator,
HbmSimpleValueRelationalStateContainer container) {
if ( discriminator.getColumn() != null ) {
throw new IllegalArgumentException(
"This method should not be called with null discriminator.getColumnElement()"
);
}
this.container = container;
this.explicitColumnName = null;
this.size = createSize( discriminator.getLength(), null, null );
this.isNullable = false;
this.isUnique = true;
this.checkCondition = null;
this.defaultColumnValue = null;
this.sqlType = null;
this.customWrite = null;
this.customRead = null;
this.comment = null;
this.uniqueKeys = container.getPropertyUniqueKeys();
this.indexes = container.getPropertyIndexes();
}
HbmColumnRelationalState(XMLVersion version,
HbmSimpleValueRelationalStateContainer container) {
this.container = container;
this.explicitColumnName = version.getColumnAttribute();
if ( version.getColumn() != null && !version.getColumn().isEmpty() ) {
throw new IllegalArgumentException(
"This method should not be called with non-empty version.getColumnElement()"
);
}
// TODO: should set default
this.size = new Size();
this.isNullable = false;
this.isUnique = false;
this.checkCondition = null;
this.defaultColumnValue = null;
this.sqlType = null;
this.customWrite = null;
this.customRead = null;
this.comment = null;
this.uniqueKeys = container.getPropertyUniqueKeys();
this.indexes = container.getPropertyIndexes();
}
HbmColumnRelationalState(XMLTimestamp timestamp,
HbmSimpleValueRelationalStateContainer container) {
this.container = container;
this.explicitColumnName = timestamp.getColumn();
// TODO: should set default
this.size = new Size();
this.isNullable = false;
this.isUnique = true; // well, it should hopefully be unique...
this.checkCondition = null;
this.defaultColumnValue = null;
this.sqlType = null;
this.customWrite = null;
this.customRead = null;
this.comment = null;
this.uniqueKeys = container.getPropertyUniqueKeys();
this.indexes = container.getPropertyIndexes();
}
public NamingStrategy getNamingStrategy() {
return container.getNamingStrategy();
}
public boolean isGloballyQuotedIdentifiers(){
return container.isGloballyQuotedIdentifiers();
}
public String getExplicitColumnName() {
return explicitColumnName;
}
public Size getSize() {
return size;
}
protected static Size createSize(String length, String scale, String precision) {
// TODO: should this set defaults if length, scale, precision is not specified?
Size size = new Size();
if ( length != null ) {
size.setLength( Integer.parseInt( length ) );
}
if ( scale != null ) {
size.setScale( Integer.parseInt( scale ) );
}
if ( precision != null ) {
size.setPrecision( Integer.parseInt( precision ) );
}
// TODO: is there an attribute for lobMultiplier?
return size;
}
public boolean isNullable() {
return isNullable;
}
public boolean isUnique() {
return isUnique;
}
public String getCheckCondition() {
return checkCondition;
}
public String getDefault() {
return defaultColumnValue;
}
public String getSqlType() {
return sqlType;
}
public String getCustomWriteFragment() {
return customWrite;
}
public String getCustomReadFragment() {
return customRead;
}
public String getComment() {
return comment;
}
public Set<String> getUniqueKeys() {
return uniqueKeys;
}
public Set<String> getIndexes() {
return indexes;
}
}

View File

@ -1,233 +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.source.hbm.state.relational;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.hibernate.MappingException;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.metamodel.source.BindingContext;
import org.hibernate.metamodel.binding.HibernateTypeDescriptor;
import org.hibernate.metamodel.relational.state.SimpleValueRelationalState;
import org.hibernate.metamodel.relational.state.TupleRelationalState;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLColumnElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLDiscriminator;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLId;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLTimestamp;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping.XMLClass.XMLVersion;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLPropertyElement;
/**
* @author Gail Badner
*/
public class HbmSimpleValueRelationalStateContainer implements TupleRelationalState {
private final BindingContext bindingContext;
private final Set<String> propertyUniqueKeys;
private final Set<String> propertyIndexes;
private final List<SimpleValueRelationalState> simpleValueStates;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
public BindingContext getBindingContext() {
return bindingContext;
}
public boolean isGloballyQuotedIdentifiers(){
return getBindingContext().isGloballyQuotedIdentifiers();
}
public NamingStrategy getNamingStrategy() {
return getBindingContext().getNamingStrategy();
}
// TODO: remove duplication after Id, Discriminator, Version, Timestamp, and Property extend a common interface.
public HbmSimpleValueRelationalStateContainer(
BindingContext bindingContext,
boolean autoColumnCreation,
XMLId id) {
this( bindingContext, id.getColumn() );
if ( simpleValueStates.isEmpty() ) {
if ( id.getColumn() == null && ! autoColumnCreation ) {
throw new MappingException( "No columns to map and auto column creation is disabled." );
}
simpleValueStates.add( new HbmColumnRelationalState( id, this ) );
}
else if ( id.getColumn() != null ) {
throw new MappingException( "column attribute may not be used together with <column> subelement" );
}
this.hibernateTypeDescriptor.setExplicitTypeName( id.getTypeAttribute() );
}
public HbmSimpleValueRelationalStateContainer(
BindingContext bindingContext,
boolean autoColumnCreation,
XMLDiscriminator discriminator) {
this( bindingContext, discriminator.getFormula(), discriminator.getColumn() );
if ( simpleValueStates.isEmpty() ) {
if ( discriminator.getColumn() == null && discriminator.getFormula() == null && ! autoColumnCreation ) {
throw new MappingException( "No column or formula to map and auto column creation is disabled." );
}
simpleValueStates.add( new HbmColumnRelationalState( discriminator, this ) );
}
else if ( discriminator.getColumn() != null || discriminator.getFormula() != null) {
throw new MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement" );
}
this.hibernateTypeDescriptor.setExplicitTypeName(
discriminator.getType() == null ?
"string" :
discriminator.getType()
);
}
public HbmSimpleValueRelationalStateContainer(
BindingContext bindingContext,
boolean autoColumnCreation,
XMLVersion version) {
this( bindingContext, version.getColumn() );
if ( simpleValueStates.isEmpty() ) {
if ( version.getColumn() == null && ! autoColumnCreation ) {
throw new MappingException( "No column or formula to map and auto column creation is disabled." );
}
simpleValueStates.add( new HbmColumnRelationalState( version, this ) );
}
else if ( version.getColumn() != null ) {
throw new MappingException( "column attribute may not be used together with <column> subelement" );
}
this.hibernateTypeDescriptor.setExplicitTypeName( version.getType() == null ? "integer" : version.getType() );
}
public HbmSimpleValueRelationalStateContainer(
BindingContext bindingContext,
boolean autoColumnCreation,
XMLTimestamp timestamp) {
this( bindingContext, null );
if ( simpleValueStates.isEmpty() ) {
if ( timestamp.getColumn() == null && ! autoColumnCreation ) {
throw new MappingException( "No columns to map and auto column creation is disabled." );
}
simpleValueStates.add( new HbmColumnRelationalState( timestamp, this ) );
}
else if ( timestamp.getColumn() != null ) {
throw new MappingException( "column attribute may not be used together with <column> subelement" );
}
this.hibernateTypeDescriptor.setExplicitTypeName(
"db".equals( timestamp.getSource() ) ?
"dbtimestamp" :
"timestamp"
);
}
public HbmSimpleValueRelationalStateContainer(
BindingContext bindingContext,
boolean autoColumnCreation,
XMLPropertyElement property) {
this( bindingContext, property.getColumnOrFormula() );
if ( simpleValueStates.isEmpty() ) {
if ( property.getColumn() == null && property.getFormula() == null && ! autoColumnCreation ) {
throw new MappingException( "No column or formula to map and auto column creation is disabled." );
}
simpleValueStates.add( new HbmColumnRelationalState( property, this ) );
}
else if ( property.getColumn() != null || property.getFormula() != null) {
throw new MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement" );
}
this.hibernateTypeDescriptor.setExplicitTypeName( property.getTypeAttribute() );
}
public HbmSimpleValueRelationalStateContainer(
BindingContext bindingContext,
boolean autoColumnCreation,
XMLManyToOneElement manyToOne) {
this( bindingContext, manyToOne.getColumnOrFormula() );
if ( simpleValueStates.isEmpty() ) {
if ( manyToOne.getColumn() == null && manyToOne.getFormula() == null && ! autoColumnCreation ) {
throw new MappingException( "No column or formula to map and auto column creation is disabled." );
}
simpleValueStates.add( new HbmColumnRelationalState( manyToOne, this ) );
}
else if ( manyToOne.getColumn() != null || manyToOne.getFormula() != null) {
throw new MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement" );
}
}
private HbmSimpleValueRelationalStateContainer(
BindingContext bindingContext,
String formulaElement,
XMLColumnElement columnElement) {
this( bindingContext,
formulaElement != null
? Collections.singletonList( formulaElement )
: columnElement != null
? Collections.singletonList( columnElement )
: Collections.<Object>emptyList()
);
}
private HbmSimpleValueRelationalStateContainer(
BindingContext bindingContext,
List mappedColumnsOrFormulas) {
this.bindingContext = bindingContext;
this.propertyUniqueKeys = Collections.emptySet();
this.propertyIndexes = Collections.emptySet();
simpleValueStates = new ArrayList<SimpleValueRelationalState>(
mappedColumnsOrFormulas == null || mappedColumnsOrFormulas.isEmpty()
? 1
: mappedColumnsOrFormulas.size()
);
if ( mappedColumnsOrFormulas != null && ! mappedColumnsOrFormulas.isEmpty() ) {
for ( Object mappedColumnOrFormula : mappedColumnsOrFormulas ) {
simpleValueStates.add( createColumnOrFormulaRelationalState( this, mappedColumnOrFormula ) );
}
}
}
private static SimpleValueRelationalState createColumnOrFormulaRelationalState(
HbmSimpleValueRelationalStateContainer container,
Object columnOrFormula) {
if ( XMLColumnElement.class.isInstance( columnOrFormula ) ) {
return new HbmColumnRelationalState(
XMLColumnElement.class.cast( columnOrFormula ),
container
);
}
else if ( String.class.isInstance( columnOrFormula ) ) {
return new HbmDerivedValueRelationalState( String.class.cast( columnOrFormula ) );
}
throw new MappingException( "unknown type of column or formula: " + columnOrFormula.getClass().getName() );
}
public List<SimpleValueRelationalState> getRelationalStates() {
return simpleValueStates;
}
Set<String> getPropertyUniqueKeys() {
return propertyUniqueKeys;
}
Set<String> getPropertyIndexes() {
return propertyIndexes;
}
}

View File

@ -27,28 +27,28 @@ import org.hibernate.MappingException;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.EntityReferencingAttributeBinding;
import org.hibernate.metamodel.binding.SingularAssociationAttributeBinding;
/**
* @author Gail Badner
*/
class EntityReferenceResolver {
class AssociationResolver {
private final MetadataImplementor metadata;
EntityReferenceResolver(MetadataImplementor metadata) {
AssociationResolver(MetadataImplementor metadata) {
this.metadata = metadata;
}
void resolve() {
for ( EntityBinding entityBinding : metadata.getEntityBindings() ) {
for ( EntityReferencingAttributeBinding attributeBinding : entityBinding.getEntityReferencingAttributeBindings() ) {
for ( SingularAssociationAttributeBinding attributeBinding : entityBinding.getEntityReferencingAttributeBindings() ) {
resolve( attributeBinding );
}
}
}
private void resolve(EntityReferencingAttributeBinding attributeBinding) {
private void resolve(SingularAssociationAttributeBinding attributeBinding) {
if ( attributeBinding.getReferencedEntityName() == null ) {
throw new IllegalArgumentException( "attributeBinding has null entityName: " + attributeBinding.getAttribute().getName() );
}

View File

@ -168,7 +168,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
bindMappingDependentMetadata( metadataSourceProcessors, metadataSources );
// todo : remove this by coordinated ordering of entity processing
new EntityReferenceResolver( this ).resolve();
new AssociationResolver( this ).resolve();
new AttributeTypeResolver( this ).resolve();
// IdentifierGeneratorResolver.resolve() must execute after AttributeTypeResolver.resolve()
new IdentifierGeneratorResolver( this ).resolve();

View File

@ -105,17 +105,17 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
EntityBinding simpleEntityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() );
assertIdAndSimpleProperty( simpleEntityBinding );
Set<EntityReferencingAttributeBinding> referenceBindings = simpleEntityBinding.getAttributeBinding( "id" )
Set<SingularAssociationAttributeBinding> referenceBindings = simpleEntityBinding.getAttributeBinding( "id" )
.getEntityReferencingAttributeBindings();
assertEquals( "There should be only one reference binding", 1, referenceBindings.size() );
EntityReferencingAttributeBinding referenceBinding = referenceBindings.iterator().next();
SingularAssociationAttributeBinding referenceBinding = referenceBindings.iterator().next();
EntityBinding referencedEntityBinding = referenceBinding.getReferencedEntityBinding();
// TODO - Is this assertion correct (HF)?
assertEquals( "Should be the same entity binding", referencedEntityBinding, simpleEntityBinding );
EntityBinding entityWithManyToOneBinding = metadata.getEntityBinding( ManyToOneEntity.class.getName() );
Iterator<EntityReferencingAttributeBinding> it = entityWithManyToOneBinding.getEntityReferencingAttributeBindings()
Iterator<SingularAssociationAttributeBinding> it = entityWithManyToOneBinding.getEntityReferencingAttributeBindings()
.iterator();
assertTrue( it.hasNext() );
assertSame( entityWithManyToOneBinding.getAttributeBinding( "simpleEntity" ), it.next() );