HHH-6447 - Develop shared binding creation approach

This commit is contained in:
Steve Ebersole 2011-07-15 18:09:59 -05:00
parent 0c7498e31d
commit d3d1fdf423
28 changed files with 1892 additions and 2114 deletions

View File

@ -62,8 +62,8 @@ public class EntityBinding {
private Class<? extends EntityPersister> customEntityPersisterClass;
private Class<? extends EntityTuplizer> customEntityTuplizerClass;
private boolean isRoot;
private InheritanceType entityInheritanceType;
private EntityBinding superEntityBinding;
private final EntityIdentifier entityIdentifier = new EntityIdentifier( this );
private EntityDiscriminator entityDiscriminator;
@ -170,29 +170,7 @@ public void setBaseTable(TableSpecification baseTable) {
}
public boolean isRoot() {
return isRoot;
}
public void setRoot(boolean isRoot) {
this.isRoot = isRoot;
}
public EntityIdentifier getEntityIdentifier() {
return entityIdentifier;
}
public void bindEntityIdentifier(SimpleAttributeBinding attributeBinding) {
if ( !Column.class.isInstance( attributeBinding.getValue() ) ) {
throw new MappingException(
"Identifier value must be a Column; instead it is: " + attributeBinding.getValue().getClass()
);
}
entityIdentifier.setValueBinding( attributeBinding );
baseTable.getPrimaryKey().addColumn( Column.class.cast( attributeBinding.getValue() ) );
}
public EntityDiscriminator getEntityDiscriminator() {
return entityDiscriminator;
return superEntityBinding == null;
}
public void setInheritanceType(InheritanceType entityInheritanceType) {
@ -203,6 +181,22 @@ public InheritanceType getInheritanceType() {
return entityInheritanceType;
}
public void setSuperEntityBinding(EntityBinding superEntityBinding) {
this.superEntityBinding = superEntityBinding;
}
public EntityBinding getSuperEntityBinding() {
return superEntityBinding;
}
public EntityIdentifier getEntityIdentifier() {
return entityIdentifier;
}
public EntityDiscriminator getEntityDiscriminator() {
return entityDiscriminator;
}
public boolean isVersioned() {
return versionBinding != null;
}

View File

@ -26,6 +26,7 @@
import java.util.Iterator;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.metamodel.binding.state.ManyToOneAttributeBindingState;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.ForeignKey;
@ -36,6 +37,7 @@
* TODO : javadoc
*
* @author Gail Badner
* @author Steve Ebersole
*/
public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements EntityReferencingAttributeBinding {
private String referencedAttributeName;
@ -46,6 +48,8 @@ public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements
private AttributeBinding referencedAttributeBinding;
private Iterable<CascadeStyle> cascadeStyles;
ManyToOneAttributeBinding(EntityBinding entityBinding) {
super( entityBinding, false, false );
}
@ -89,18 +93,22 @@ public void setReferencedAttributeName(String referencedEntityAttributeName) {
this.referencedAttributeName = referencedEntityAttributeName;
}
@Override
public Iterable<CascadeStyle> getCascadeStyles() {
return cascadeStyles;
}
@Override
public void setCascadeStyles(Iterable<CascadeStyle> cascadeStyles) {
this.cascadeStyles = cascadeStyles;
}
@Override
public final boolean isReferenceResolved() {
return referencedAttributeBinding != null;
}
public final EntityBinding getReferencedEntityBinding() {
if ( !isReferenceResolved() ) {
throw new IllegalStateException( "EntityBinding reference has not be referenced." );
}
// TODO: throw exception if referencedEntityBinding is null?
return referencedAttributeBinding.getEntityBinding();
}
@Override
public final void resolveReference(AttributeBinding referencedAttributeBinding) {
if ( !referencedEntityName.equals( referencedAttributeBinding.getEntityBinding().getEntity().getName() ) ) {
throw new IllegalStateException(
@ -122,6 +130,19 @@ else if ( !referencedAttributeName.equals( referencedAttributeBinding.getAttribu
buildForeignKey();
}
@Override
public AttributeBinding getReferencedAttributeBinding() {
if ( !isReferenceResolved() ) {
throw new IllegalStateException( "Referenced AttributeBiding has not been resolved." );
}
return referencedAttributeBinding;
}
@Override
public final EntityBinding getReferencedEntityBinding() {
return referencedAttributeBinding.getEntityBinding();
}
private void buildForeignKey() {
// TODO: move this stuff to relational model
ForeignKey foreignKey = getValue().getTable()

View File

@ -199,6 +199,7 @@ private void indexClass(Indexer indexer, String className) {
throw new HibernateException( "Unable to open input stream for class " + className, e );
}
}
}

View File

@ -183,7 +183,6 @@ private EntityBinding buildBasicEntityBinding() {
private EntityBinding doRootEntityBindingCreation() {
EntityBinding entityBinding = new EntityBinding();
entityBinding.setInheritanceType( InheritanceType.NO_INHERITANCE );
entityBinding.setRoot( entityClass.isEntityRoot() );
doBasicEntityBinding( entityBinding );

View File

@ -32,6 +32,7 @@
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.beans.BeanInfoHelper;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.InheritanceType;
@ -43,6 +44,8 @@
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Identifier;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.Tuple;
@ -61,6 +64,7 @@ public class Binder {
private final List<String> processedEntityNames;
private InheritanceType currentInheritanceType;
private EntityMode currentHierarchyEntityMode;
private LocalBindingContext currentBindingContext;
public Binder(MetadataImplementor metadata, List<String> processedEntityNames) {
@ -74,6 +78,7 @@ public void processEntityHierarchy(EntityHierarchy entityHierarchy) {
if ( currentInheritanceType != InheritanceType.NO_INHERITANCE ) {
processHierarchySubEntities( entityHierarchy.getRootEntitySource(), rootEntityBinding );
}
currentHierarchyEntityMode = null;
}
private void processHierarchySubEntities(SubclassEntityContainer subclassEntitySource, EntityBinding superEntityBinding) {
@ -97,6 +102,9 @@ private EntityBinding createEntityBinding(EntitySource entitySource, EntityBindi
metadata.addEntity( entityBinding );
processedEntityNames.add( entityBinding.getEntity().getName() );
processFetchProfiles( entitySource, entityBinding );
return entityBinding;
}
finally {
@ -110,7 +118,7 @@ private EntityBinding doCreateEntityBinding(EntitySource entitySource, EntityBin
bindSecondaryTables( entitySource, entityBinding );
bindAttributes( entitySource, entityBinding );
bindTableUniqueConstraints( entityBinding );
bindTableUniqueConstraints( entitySource, entityBinding );
return entityBinding;
}
@ -121,13 +129,13 @@ private EntityBinding createBasicEntityBinding(EntitySource entitySource, Entity
}
else {
if ( currentInheritanceType == InheritanceType.SINGLE_TABLE ) {
return makeDiscriminatedSubclassBinding( entitySource, superEntityBinding );
return makeDiscriminatedSubclassBinding( (SubclassEntitySource) entitySource, superEntityBinding );
}
else if ( currentInheritanceType == InheritanceType.JOINED ) {
return makeJoinedSubclassBinding( entitySource, superEntityBinding );
return makeJoinedSubclassBinding( (SubclassEntitySource) entitySource, superEntityBinding );
}
else if ( currentInheritanceType == InheritanceType.TABLE_PER_CLASS ) {
return makeUnionedSubclassBinding( entitySource, superEntityBinding );
return makeUnionedSubclassBinding( (SubclassEntitySource) entitySource, superEntityBinding );
}
else {
// extreme internal error!
@ -137,27 +145,11 @@ else if ( currentInheritanceType == InheritanceType.TABLE_PER_CLASS ) {
}
private EntityBinding makeRootEntityBinding(RootEntitySource entitySource) {
final EntityBinding entityBinding = new EntityBinding();
entityBinding.setInheritanceType( currentInheritanceType );
entityBinding.setRoot( true );
currentHierarchyEntityMode = entitySource.getEntityMode();
final EntityMode entityMode = entitySource.getEntityMode();
entityBinding.setEntityMode( entityMode );
final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, null );
final String entityName = entitySource.getEntityName();
final String className = entityMode == EntityMode.POJO ? entitySource.getClassName() : null;
final Entity entity = new Entity(
entityName,
className,
currentBindingContext.makeClassReference( className ),
null
);
entityBinding.setEntity( entity );
performBasicEntityBind( entitySource, entityBinding );
bindPrimaryTable( entityBinding, entitySource );
bindPrimaryTable( entitySource, entityBinding );
bindIdentifier( entitySource, entityBinding );
bindVersion( entityBinding, entitySource );
@ -173,19 +165,25 @@ private EntityBinding makeRootEntityBinding(RootEntitySource entitySource) {
return entityBinding;
}
private EntityBinding makeDiscriminatedSubclassBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
return null; //To change body of created methods use File | Settings | File Templates.
}
private EntityBinding makeJoinedSubclassBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
return null; //To change body of created methods use File | Settings | File Templates.
}
private EntityBinding buildBasicEntityBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
final EntityBinding entityBinding = new EntityBinding();
entityBinding.setSuperEntityBinding( superEntityBinding );
entityBinding.setInheritanceType( currentInheritanceType );
private EntityBinding makeUnionedSubclassBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
return null; //To change body of created methods use File | Settings | File Templates.
}
entityBinding.setEntityMode( currentHierarchyEntityMode );
final String entityName = entitySource.getEntityName();
final String className = currentHierarchyEntityMode == EntityMode.POJO ? entitySource.getClassName() : null;
final Entity entity = new Entity(
entityName,
className,
currentBindingContext.makeClassReference( className ),
null
);
entityBinding.setEntity( entity );
private void performBasicEntityBind(EntitySource entitySource, EntityBinding entityBinding) {
entityBinding.setJpaEntityName( entitySource.getJpaEntityName() );
if ( entityBinding.getEntityMode() == EntityMode.POJO ) {
@ -234,6 +232,54 @@ else if ( entitySource.isLazy() ) {
if ( entitySource.getSynchronizedTableNames() != null ) {
entityBinding.addSynchronizedTableNames( entitySource.getSynchronizedTableNames() );
}
return entityBinding;
}
private EntityBinding makeDiscriminatedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) {
final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding );
entityBinding.setBaseTable( superEntityBinding.getBaseTable() );
bindDiscriminatorValue( entitySource, entityBinding );
return entityBinding;
}
private EntityBinding makeJoinedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) {
final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding );
bindPrimaryTable( entitySource, entityBinding );
// todo : join
return entityBinding;
}
private EntityBinding makeUnionedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) {
final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding );
bindPrimaryTable( entitySource, entityBinding );
// todo : ??
return entityBinding;
}
// 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) {
@ -245,9 +291,12 @@ private void bindIdentifier(RootEntitySource entitySource, EntityBinding entityB
bindSimpleIdentifier( (SimpleIdentifierSource) entitySource.getIdentifierSource(), entityBinding );
}
case AGGREGATED_COMPOSITE: {
// composite id with an actual component class
}
case COMPOSITE: {
// what we used to term an "embedded composite identifier", which is not tobe confused with the JPA
// term embedded. Specifically a composite id where there is no component class, though there may
// be a @IdClass :/
}
}
}
@ -291,16 +340,11 @@ private void bindVersion(EntityBinding entityBinding, RootEntitySource entitySou
}
private void bindDiscriminator(RootEntitySource entitySource, EntityBinding entityBinding) {
//To change body of created methods use File | Settings | File Templates.
// todo : implement
}
private void bindAttributes(EntitySource entitySource, EntityBinding entityBinding) {
for ( AttributeSource attributeSource : entitySource.attributeSources() ) {
if ( attributeSource.isSingular() ) {
doBasicSingularAttributeBindingCreation( (SingularAttributeSource) attributeSource, entityBinding );
}
// todo : components and collections
}
private void bindDiscriminatorValue(SubclassEntitySource entitySource, EntityBinding entityBinding) {
// todo : implement
}
private SimpleAttributeBinding doBasicSingularAttributeBindingCreation(
@ -415,6 +459,7 @@ private void resolveToOneReferenceInformation(ToOneAttributeSource attributeSour
? 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() );
}
@ -456,6 +501,50 @@ private static MetaAttributeContext buildMetaAttributeContext(
return subContext;
}
// Relational ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void bindPrimaryTable(EntitySource entitySource, EntityBinding entityBinding) {
final TableSource tableSource = entitySource.getPrimaryTable();
final String schemaName = StringHelper.isEmpty( tableSource.getExplicitSchemaName() )
? currentBindingContext.getMappingDefaults().getSchemaName()
: currentBindingContext.getMetadataImplementor().getOptions().isGloballyQuotedIdentifiers()
? StringHelper.quote( tableSource.getExplicitSchemaName() )
: tableSource.getExplicitSchemaName();
final String catalogName = StringHelper.isEmpty( tableSource.getExplicitCatalogName() )
? currentBindingContext.getMappingDefaults().getCatalogName()
: currentBindingContext.getMetadataImplementor().getOptions().isGloballyQuotedIdentifiers()
? StringHelper.quote( tableSource.getExplicitCatalogName() )
: tableSource.getExplicitCatalogName();
String tableName = tableSource.getExplicitTableName();
if ( StringHelper.isEmpty( tableName ) ) {
tableName = currentBindingContext.getNamingStrategy()
.classToTableName( entityBinding.getEntity().getClassName() );
}
else {
tableName = currentBindingContext.getNamingStrategy().tableName( tableName );
}
if ( currentBindingContext.isGloballyQuotedIdentifiers() ) {
tableName = StringHelper.quote( tableName );
}
final org.hibernate.metamodel.relational.Table table = currentBindingContext.getMetadataImplementor()
.getDatabase()
.getSchema( new Schema.Name( schemaName, catalogName ) )
.locateOrCreateTable( Identifier.toIdentifier( tableName ) );
entityBinding.setBaseTable( table );
}
private void bindSecondaryTables(EntitySource entitySource, EntityBinding entityBinding) {
// todo : implement
}
private void bindTableUniqueConstraints(EntitySource entitySource, EntityBinding entityBinding) {
// todo : implement
}
private org.hibernate.metamodel.relational.Value makeValue(
RelationValueMetadataSource relationValueMetadataSource,
SimpleAttributeBinding attributeBinding) {
@ -505,4 +594,8 @@ private org.hibernate.metamodel.relational.Value makeValue(
}
}
private void processFetchProfiles(EntitySource entitySource, EntityBinding entityBinding) {
// todo : process the entity-local fetch-profile declaration
}
}

View File

@ -40,6 +40,8 @@ public interface EntitySource extends SubclassEntityContainer, AttributeSourceCo
public String getClassName();
public String getJpaEntityName();
public TableSource getPrimaryTable();
public boolean isAbstract();
public boolean isLazy();
public String getProxy();

View File

@ -30,5 +30,6 @@
* @author Steve Ebersole
*/
public interface SubclassEntityContainer {
public void add(SubclassEntitySource subclassEntitySource);
public Iterable<SubclassEntitySource> subclassEntitySources();
}

View File

@ -21,23 +21,13 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.source.hbm;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
package org.hibernate.metamodel.source.binder;
/**
* A sub entity within an entity hierarchy.
*
* @author Steve Ebersole
*/
public class EntityHierarchySubEntity extends AbstractSubEntityContainer {
private final EntitySourceInformation entitySourceInformation;
public EntityHierarchySubEntity(EntityElement entityElement, MappingDocument sourceMappingDocument) {
this.entitySourceInformation = new EntitySourceInformation( entityElement, sourceMappingDocument );
}
public EntitySourceInformation getEntitySourceInformation() {
return entitySourceInformation;
}
public interface TableSource {
public String getExplicitSchemaName();
public String getExplicitCatalogName();
public String getExplicitTableName();
}

View File

@ -0,0 +1,245 @@
/*
* 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;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.EntityMode;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.binding.CustomSQL;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.Origin;
import org.hibernate.metamodel.source.binder.AttributeSource;
import org.hibernate.metamodel.source.binder.EntitySource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.SubclassEntitySource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLAnyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToManyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToManyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToOneElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLPropertyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSynchronizeElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLTuplizerElement;
/**
* @author Steve Ebersole
*/
public abstract class AbstractEntitySourceImpl implements EntitySource {
private final MappingDocument sourceMappingDocument;
private final EntityElement entityElement;
private List<SubclassEntitySource> subclassEntitySources = new ArrayList<SubclassEntitySource>();
protected AbstractEntitySourceImpl(MappingDocument sourceMappingDocument, EntityElement entityElement) {
this.sourceMappingDocument = sourceMappingDocument;
this.entityElement = entityElement;
}
protected EntityElement entityElement() {
return entityElement;
}
protected MappingDocument sourceMappingDocument() {
return sourceMappingDocument;
}
@Override
public Origin getOrigin() {
return sourceMappingDocument.getOrigin();
}
@Override
public LocalBindingContext getBindingContext() {
return sourceMappingDocument.getMappingLocalBindingContext();
}
@Override
public String getEntityName() {
return StringHelper.isNotEmpty( entityElement.getEntityName() )
? entityElement.getEntityName()
: getClassName();
}
@Override
public String getClassName() {
return getBindingContext().qualifyClassName( entityElement.getName() );
}
@Override
public String getJpaEntityName() {
return null;
}
@Override
public boolean isAbstract() {
return Helper.getBooleanValue( entityElement.isAbstract(), false );
}
@Override
public boolean isLazy() {
return Helper.getBooleanValue( entityElement.isAbstract(), true );
}
@Override
public String getProxy() {
return entityElement.getProxy();
}
@Override
public int getBatchSize() {
return Helper.getIntValue( entityElement.getBatchSize(), -1 );
}
@Override
public boolean isDynamicInsert() {
return entityElement.isDynamicInsert();
}
@Override
public boolean isDynamicUpdate() {
return entityElement.isDynamicUpdate();
}
@Override
public boolean isSelectBeforeUpdate() {
return entityElement.isSelectBeforeUpdate();
}
protected EntityMode determineEntityMode() {
return StringHelper.isNotEmpty( getClassName() ) ? EntityMode.POJO : EntityMode.MAP;
}
@Override
public String getCustomTuplizerClassName() {
if ( entityElement.getTuplizer() == null ) {
return null;
}
final EntityMode entityMode = determineEntityMode();
for ( XMLTuplizerElement tuplizerElement : entityElement.getTuplizer() ) {
if ( entityMode == EntityMode.parse( tuplizerElement.getEntityMode() ) ) {
return tuplizerElement.getClazz();
}
}
return null;
}
@Override
public String getCustomPersisterClassName() {
return getBindingContext().qualifyClassName( entityElement.getPersister() );
}
@Override
public String getCustomLoaderName() {
return entityElement.getLoader() != null ? entityElement.getLoader().getQueryRef() : null;
}
@Override
public CustomSQL getCustomSqlInsert() {
return Helper.buildCustomSql( entityElement.getSqlInsert() );
}
@Override
public CustomSQL getCustomSqlUpdate() {
return Helper.buildCustomSql( entityElement.getSqlUpdate() );
}
@Override
public CustomSQL getCustomSqlDelete() {
return Helper.buildCustomSql( entityElement.getSqlDelete() );
}
@Override
public List<String> getSynchronizedTableNames() {
List<String> tableNames = new ArrayList<String>();
for ( XMLSynchronizeElement synchronizeElement : entityElement.getSynchronize() ) {
tableNames.add( synchronizeElement.getTable() );
}
return tableNames;
}
@Override
public Iterable<MetaAttributeSource> metaAttributes() {
return Helper.buildMetaAttributeSources( entityElement.getMeta() );
}
@Override
public Iterable<AttributeSource> attributeSources() {
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
for ( Object attributeElement : entityElement.getPropertyOrManyToOneOrOneToOne() ) {
if ( XMLPropertyElement.class.isInstance( attributeElement ) ) {
attributeSources.add(
new PropertyAttributeSourceImpl(
XMLPropertyElement.class.cast( attributeElement ),
sourceMappingDocument().getMappingLocalBindingContext()
)
);
}
else if ( XMLManyToOneElement.class.isInstance( attributeElement ) ) {
attributeSources.add(
new ManyToOneAttributeSourceImpl(
XMLManyToOneElement.class.cast( attributeElement ),
sourceMappingDocument().getMappingLocalBindingContext()
)
);
}
else if ( XMLOneToOneElement.class.isInstance( attributeElement ) ) {
// todo : implement
}
else if ( XMLAnyElement.class.isInstance( attributeElement ) ) {
// todo : implement
}
else if ( XMLOneToManyElement.class.isInstance( attributeElement ) ) {
// todo : implement
}
else if ( XMLManyToManyElement.class.isInstance( attributeElement ) ) {
// todo : implement
}
}
return attributeSources;
}
private EntityHierarchyImpl entityHierarchy;
public void injectHierarchy(EntityHierarchyImpl entityHierarchy) {
this.entityHierarchy = entityHierarchy;
}
@Override
public void add(SubclassEntitySource subclassEntitySource) {
add( (SubclassEntitySourceImpl) subclassEntitySource );
}
public void add(SubclassEntitySourceImpl subclassEntitySource) {
entityHierarchy.processSubclass( subclassEntitySource );
subclassEntitySources.add( subclassEntitySource );
}
@Override
public Iterable<SubclassEntitySource> subclassEntitySources() {
return subclassEntitySources;
}
}

View File

@ -1,48 +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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Steve Ebersole
*/
public class AbstractSubEntityContainer implements SubEntityContainer {
private List<EntityHierarchySubEntity> subEntityDescriptors;
public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor) {
if ( subEntityDescriptors == null ) {
subEntityDescriptors = new ArrayList<EntityHierarchySubEntity>();
}
subEntityDescriptors.add( subEntityDescriptor );
}
public Iterable<EntityHierarchySubEntity> subEntityDescriptors() {
return subEntityDescriptors == null
? Collections.<EntityHierarchySubEntity>emptyList()
: subEntityDescriptors;
}
}

View File

@ -23,33 +23,72 @@
*/
package org.hibernate.metamodel.source.hbm;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.Size;
import org.hibernate.metamodel.source.binder.ColumnSource;
/**
* An aggregation of information about the source of an entity mapping.
*
* @author Steve Ebersole
*/
public class EntitySourceInformation {
private final EntityElement entityElement;
private final MappingDocument sourceMappingDocument;
private final String mappedEntityName;
* @author Steve Ebersole
*/
class ColumnAttributeSourceImpl implements ColumnSource {
private final String columnName;
public EntitySourceInformation(EntityElement entityElement, MappingDocument sourceMappingDocument) {
this.entityElement = entityElement;
this.sourceMappingDocument = sourceMappingDocument;
this.mappedEntityName = sourceMappingDocument.getMappingLocalBindingContext().determineEntityName( entityElement );
ColumnAttributeSourceImpl(String columnName) {
this.columnName = columnName;
}
public EntityElement getEntityElement() {
return entityElement;
@Override
public String getName() {
return columnName;
}
public MappingDocument getSourceMappingDocument() {
return sourceMappingDocument;
@Override
public boolean isNullable() {
return true;
}
public String getMappedEntityName() {
return mappedEntityName;
@Override
public String getDefaultValue() {
return null;
}
@Override
public String getSqlType() {
return null;
}
@Override
public Datatype getDatatype() {
return null;
}
@Override
public Size getSize() {
return null;
}
@Override
public String getReadFragment() {
return null;
}
@Override
public String getWriteFragment() {
return null;
}
@Override
public boolean isUnique() {
return false;
}
@Override
public String getCheckCondition() {
return null;
}
@Override
public String getComment() {
return null;
}
}

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.source.hbm;
import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.Size;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLColumnElement;
/**
* @author Steve Ebersole
*/
class ColumnSourceImpl implements org.hibernate.metamodel.source.binder.ColumnSource {
private final XMLColumnElement columnElement;
ColumnSourceImpl(XMLColumnElement columnElement) {
this.columnElement = columnElement;
}
@Override
public String getName() {
return columnElement.getName();
}
@Override
public boolean isNullable() {
return ! columnElement.isNotNull();
}
@Override
public String getDefaultValue() {
return columnElement.getDefault();
}
@Override
public String getSqlType() {
return columnElement.getSqlType();
}
@Override
public Datatype getDatatype() {
return null;
}
@Override
public Size getSize() {
return new Size(
Helper.getIntValue( columnElement.getPrecision(), -1 ),
Helper.getIntValue( columnElement.getScale(), -1 ),
Helper.getLongValue( columnElement.getLength(), -1 ),
Size.LobMultiplier.NONE
);
}
@Override
public String getReadFragment() {
return columnElement.getRead();
}
@Override
public String getWriteFragment() {
return columnElement.getWrite();
}
@Override
public boolean isUnique() {
return columnElement.isUnique();
}
@Override
public String getCheckCondition() {
return columnElement.getCheck();
}
@Override
public String getComment() {
return columnElement.getComment();
}
}

View File

@ -24,41 +24,38 @@
package org.hibernate.metamodel.source.hbm;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping;
import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.source.binder.RootEntitySource;
/**
* Models the source view of an entity hierarchy.
*
* @author Steve Ebersole
*/
public class EntityHierarchy extends AbstractSubEntityContainer {
private final EntitySourceInformation entitySourceInformation;
public class EntityHierarchyImpl implements org.hibernate.metamodel.source.binder.EntityHierarchy {
private final RootEntitySourceImpl rootEntitySource;
private InheritanceType hierarchyInheritanceType = InheritanceType.NO_INHERITANCE;
public EntityHierarchy(XMLHibernateMapping.XMLClass rootEntity, MappingDocument sourceMappingDocument) {
this.entitySourceInformation = new EntitySourceInformation( rootEntity, sourceMappingDocument );
}
public EntitySourceInformation getEntitySourceInformation() {
return entitySourceInformation;
public EntityHierarchyImpl(RootEntitySourceImpl rootEntitySource) {
this.rootEntitySource = rootEntitySource;
this.rootEntitySource.injectHierarchy( this );
}
@Override
public InheritanceType getHierarchyInheritanceType() {
return hierarchyInheritanceType;
}
@Override
public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor) {
super.addSubEntityDescriptor( subEntityDescriptor );
public RootEntitySource getRootEntitySource() {
return rootEntitySource;
}
// check inheritance type consistency
final InheritanceType inheritanceType = Helper.interpretInheritanceType(
subEntityDescriptor.getEntitySourceInformation().getEntityElement()
);
if ( this.hierarchyInheritanceType != InheritanceType.NO_INHERITANCE
&& this.hierarchyInheritanceType != inheritanceType ) {
// throw exception
public void processSubclass(SubclassEntitySourceImpl subclassEntitySource) {
final InheritanceType inheritanceType = Helper.interpretInheritanceType( subclassEntitySource.entityElement() );
if ( hierarchyInheritanceType == InheritanceType.NO_INHERITANCE ) {
hierarchyInheritanceType = inheritanceType;
}
else if ( hierarchyInheritanceType != inheritanceType ) {
throw new MappingException( "Mixed inheritance strategies not supported", subclassEntitySource.getOrigin() );
}
this.hierarchyInheritanceType = inheritanceType;
}
}

View File

@ -23,13 +23,20 @@
*/
package org.hibernate.metamodel.source.hbm;
import org.hibernate.metamodel.source.binder.DerivedValueSource;
/**
* Contract for elements within a {@link EntityHierarchy} which can contain sub elements. Essentially this
* abstracts that common aspect away from both root and sub entities.
*
* @author Steve Ebersole
*/
public interface SubEntityContainer {
public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor);
public Iterable<EntityHierarchySubEntity> subEntityDescriptors();
* @author Steve Ebersole
*/
class FormulaImpl implements DerivedValueSource {
private final String expression;
FormulaImpl(String expression) {
this.expression = expression;
}
@Override
public String getExpression() {
return expression;
}
}

View File

@ -29,6 +29,7 @@
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.source.SourceProcessor;
import org.hibernate.metamodel.source.binder.Binder;
import org.hibernate.metamodel.source.internal.JaxbRoot;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping;
@ -41,7 +42,7 @@ public class HbmSourceProcessorImpl implements SourceProcessor {
private final MetadataImplementor metadata;
private List<HibernateMappingProcessor> processors = new ArrayList<HibernateMappingProcessor>();
private List<EntityHierarchy> entityHierarchies;
private List<EntityHierarchyImpl> entityHierarchies;
public HbmSourceProcessorImpl(MetadataImplementor metadata) {
this.metadata = metadata;
@ -50,7 +51,7 @@ public HbmSourceProcessorImpl(MetadataImplementor metadata) {
@Override
@SuppressWarnings( {"unchecked"})
public void prepare(MetadataSources sources) {
final HierarchyBuilder hierarchyBuilder = new HierarchyBuilder( metadata );
final HierarchyBuilder hierarchyBuilder = new HierarchyBuilder();
for ( JaxbRoot jaxbRoot : sources.getJaxbRootList() ) {
if ( ! XMLHibernateMapping.class.isInstance( jaxbRoot.getRoot() ) ) {
@ -82,9 +83,9 @@ public void processTypeDependentMetadata(MetadataSources sources) {
@Override
public void processMappingMetadata(MetadataSources sources, List<String> processedEntityNames) {
BindingCreator bindingCreator = new BindingCreator( metadata, processedEntityNames );
for ( EntityHierarchy entityHierarchy : entityHierarchies ) {
bindingCreator.processEntityHierarchy( entityHierarchy );
Binder binder = new Binder( metadata, processedEntityNames );
for ( EntityHierarchyImpl entityHierarchy : entityHierarchies ) {
binder.processEntityHierarchy( entityHierarchy );
}
}

View File

@ -23,22 +23,33 @@
*/
package org.hibernate.metamodel.source.hbm;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.CustomSqlElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.binding.CustomSQL;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.binding.MetaAttribute;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.CustomSqlElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLColumnElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLJoinedSubclassElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLMetaElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLParamElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSubclassElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLUnionSubclassElement;
import org.hibernate.service.ServiceRegistry;
@ -50,6 +61,19 @@
* @author Gail Badner
*/
public class Helper {
static final Iterable<CascadeStyle> NO_CASCADING = Collections.singleton( CascadeStyle.NONE );
public static final ExplicitHibernateTypeSource TO_ONE_ATTRIBUTE_TYPE_SOURCE = new ExplicitHibernateTypeSource() {
@Override
public String getName() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public Map<String, String> getParameters() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
};
public static InheritanceType interpretInheritanceType(EntityElement entityElement) {
if ( XMLSubclassElement.class.isInstance( entityElement ) ) {
return InheritanceType.SINGLE_TABLE;
@ -195,4 +219,108 @@ public static Class classForName(String className, ServiceRegistry serviceRegist
throw new MappingException( "Could not find class: " + className );
}
}
public static Iterable<CascadeStyle> interpretCascadeStyles(String cascades, LocalBindingContext bindingContext) {
final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>();
if ( StringHelper.isEmpty( cascades ) ) {
cascades = bindingContext.getMappingDefaults().getCascadeStyle();
}
for ( String cascade : StringHelper.split( cascades, "," ) ) {
cascadeStyles.add( CascadeStyle.getCascadeStyle( cascade ) );
}
return cascadeStyles;
}
public static Map<String, String> extractParameters(List<XMLParamElement> xmlParamElements) {
if ( xmlParamElements == null || xmlParamElements.isEmpty() ) {
return null;
}
final HashMap<String,String> params = new HashMap<String, String>();
for ( XMLParamElement paramElement : xmlParamElements ) {
params.put( paramElement.getName(), paramElement.getValue() );
}
return params;
}
public static Iterable<MetaAttributeSource> buildMetaAttributeSources(List<XMLMetaElement> metaElements) {
ArrayList<MetaAttributeSource> result = new ArrayList<MetaAttributeSource>();
if ( metaElements == null || metaElements.isEmpty() ) {
// do nothing
}
else {
for ( final XMLMetaElement metaElement : metaElements ) {
result.add(
new MetaAttributeSource() {
@Override
public String getName() {
return metaElement.getAttribute();
}
@Override
public String getValue() {
return metaElement.getValue();
}
@Override
public boolean isInheritable() {
return metaElement.isInherit();
}
}
);
}
}
return result;
}
public static interface ValueSourcesAdapter {
public String getColumnAttribute();
public String getFormulaAttribute();
public List getColumnOrFormulaElements();
}
public static List<RelationalValueSource> buildValueSources(
ValueSourcesAdapter valueSourcesAdapter,
LocalBindingContext bindingContext) {
List<RelationalValueSource> result = new ArrayList<RelationalValueSource>();
if ( StringHelper.isNotEmpty( valueSourcesAdapter.getColumnAttribute() ) ) {
if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
&& ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) {
throw new org.hibernate.metamodel.source.MappingException(
"column/formula attribute may not be used together with <column>/<formula> subelement",
bindingContext.getOrigin()
);
}
if ( StringHelper.isNotEmpty( valueSourcesAdapter.getFormulaAttribute() ) ) {
throw new org.hibernate.metamodel.source.MappingException(
"column and formula attributes may not be used together",
bindingContext.getOrigin()
);
}
result.add( new ColumnAttributeSourceImpl( valueSourcesAdapter.getColumnAttribute() ) );
}
else if ( StringHelper.isNotEmpty( valueSourcesAdapter.getFormulaAttribute() ) ) {
if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
&& ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) {
throw new org.hibernate.metamodel.source.MappingException(
"column/formula attribute may not be used together with <column>/<formula> subelement",
bindingContext.getOrigin()
);
}
// column/formula attribute combo checked already
result.add( new FormulaImpl( valueSourcesAdapter.getFormulaAttribute() ) );
}
else if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
&& ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) {
for ( Object columnOrFormulaElement : valueSourcesAdapter.getColumnOrFormulaElements() ) {
if ( XMLColumnElement.class.isInstance( columnOrFormulaElement ) ) {
result.add( new ColumnSourceImpl( (XMLColumnElement) columnOrFormulaElement ) );
}
else {
result.add( new FormulaImpl( (String) columnOrFormulaElement ) );
}
}
}
return result;
}
}

View File

@ -30,7 +30,8 @@
import java.util.Map;
import org.hibernate.MappingException;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.source.binder.SubclassEntityContainer;
import org.hibernate.metamodel.source.binder.SubclassEntitySource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.SubEntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping;
@ -42,21 +43,15 @@
* @author Steve Ebersole
*/
public class HierarchyBuilder {
private final MetadataImplementor metadata;
private final List<EntityHierarchy> entityHierarchies = new ArrayList<EntityHierarchy>();
private final List<EntityHierarchyImpl> entityHierarchies = new ArrayList<EntityHierarchyImpl>();
// process state
private final Map<String,SubEntityContainer> subEntityContainerMap = new HashMap<String, SubEntityContainer>();
private final Map<String,SubclassEntityContainer> subEntityContainerMap = new HashMap<String, SubclassEntityContainer>();
private final List<ExtendsQueueEntry> extendsQueue = new ArrayList<ExtendsQueueEntry>();
// mapping file specific state
private MappingDocument currentMappingDocument;
public HierarchyBuilder(MetadataImplementor metadata) {
this.metadata = metadata;
}
public void processMappingDocument(MappingDocument mappingDocument) {
this.currentMappingDocument = mappingDocument;
try {
@ -73,48 +68,48 @@ private void processCurrentMappingDocument() {
if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) {
// we can immediately handle <class/> elements in terms of creating the hierarchy entry
final XMLHibernateMapping.XMLClass xmlClass = (XMLHibernateMapping.XMLClass) entityElement;
final EntityHierarchy hierarchy = new EntityHierarchy( xmlClass, currentMappingDocument );
final RootEntitySourceImpl rootEntitySource = new RootEntitySourceImpl( currentMappingDocument, xmlClass );
final EntityHierarchyImpl hierarchy = new EntityHierarchyImpl( rootEntitySource );
entityHierarchies.add( hierarchy );
subEntityContainerMap.put( hierarchy.getEntitySourceInformation().getMappedEntityName(), hierarchy );
processSubElements( entityElement, hierarchy );
subEntityContainerMap.put( rootEntitySource.getEntityName(), rootEntitySource );
processSubElements( entityElement, rootEntitySource );
}
else {
// we have to see if this things super-type has been found yet, and if not add it to the
// extends queue
final EntityHierarchySubEntity subEntityDescriptor = new EntityHierarchySubEntity(
entityElement,
currentMappingDocument
);
final String entityName = subEntityDescriptor.getEntitySourceInformation().getMappedEntityName();
subEntityContainerMap.put( entityName, subEntityDescriptor );
final SubclassEntitySourceImpl subClassEntitySource = new SubclassEntitySourceImpl( currentMappingDocument, entityElement );
final String entityName = subClassEntitySource.getEntityName();
subEntityContainerMap.put( entityName, subClassEntitySource );
final String entityItExtends = currentMappingDocument.getMappingLocalBindingContext().qualifyClassName(
((SubEntityElement) entityElement).getExtends()
);
processSubElements( entityElement, subEntityDescriptor );
final SubEntityContainer container = subEntityContainerMap.get( entityItExtends );
processSubElements( entityElement, subClassEntitySource );
final SubclassEntityContainer container = subEntityContainerMap.get( entityItExtends );
if ( container != null ) {
// we already have this entity's super, attach it and continue
container.addSubEntityDescriptor( subEntityDescriptor );
container.add( subClassEntitySource );
}
else {
// we do not yet have the super and have to wait, so add it fto the extends queue
extendsQueue.add( new ExtendsQueueEntry( subEntityDescriptor, entityItExtends ) );
extendsQueue.add( new ExtendsQueueEntry( subClassEntitySource, entityItExtends ) );
}
}
}
}
public List<EntityHierarchy> groupEntityHierarchies() {
public List<EntityHierarchyImpl> groupEntityHierarchies() {
while ( ! extendsQueue.isEmpty() ) {
// set up a pass over the queue
int numberOfMappingsProcessed = 0;
Iterator<ExtendsQueueEntry> iterator = extendsQueue.iterator();
while ( iterator.hasNext() ) {
final ExtendsQueueEntry entry = iterator.next();
final SubEntityContainer container = subEntityContainerMap.get( entry.entityItExtends );
final SubclassEntityContainer container = subEntityContainerMap.get( entry.entityItExtends );
if ( container != null ) {
// we now have this entity's super, attach it and remove entry from extends queue
container.addSubEntityDescriptor( entry.subEntityDescriptor );
container.add( entry.subClassEntitySource );
iterator.remove();
numberOfMappingsProcessed++;
}
@ -129,7 +124,7 @@ public List<EntityHierarchy> groupEntityHierarchies() {
return entityHierarchies;
}
private void processSubElements(EntityElement entityElement, SubEntityContainer container) {
private void processSubElements(EntityElement entityElement, SubclassEntityContainer container) {
if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) {
final XMLHibernateMapping.XMLClass xmlClass = (XMLHibernateMapping.XMLClass) entityElement;
processElements( xmlClass.getJoinedSubclass(), container );
@ -150,25 +145,22 @@ else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) {
}
}
private void processElements(List subElements, SubEntityContainer container) {
private void processElements(List subElements, SubclassEntityContainer container) {
for ( Object subElementO : subElements ) {
final SubEntityElement subElement = (SubEntityElement) subElementO;
final EntityHierarchySubEntity subEntityDescriptor = new EntityHierarchySubEntity(
subElement,
currentMappingDocument
);
container.addSubEntityDescriptor( subEntityDescriptor );
final String subEntityName = subEntityDescriptor.getEntitySourceInformation().getMappedEntityName();
subEntityContainerMap.put( subEntityName, subEntityDescriptor );
final SubclassEntitySourceImpl subclassEntitySource = new SubclassEntitySourceImpl( currentMappingDocument, subElement );
container.add( subclassEntitySource );
final String subEntityName = subclassEntitySource.getEntityName();
subEntityContainerMap.put( subEntityName, subclassEntitySource );
}
}
private static class ExtendsQueueEntry {
private final EntityHierarchySubEntity subEntityDescriptor;
private final SubclassEntitySource subClassEntitySource;
private final String entityItExtends;
private ExtendsQueueEntry(EntityHierarchySubEntity subEntityDescriptor, String entityItExtends) {
this.subEntityDescriptor = subEntityDescriptor;
private ExtendsQueueEntry(SubclassEntitySource subClassEntitySource, String entityItExtends) {
this.subClassEntitySource = subClassEntitySource;
this.entityItExtends = entityItExtends;
}
}

View File

@ -0,0 +1,153 @@
/*
* 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;
import java.util.List;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.binder.ToOneAttributeSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement;
/**
* Implementation for {@code <many-to-one/> mappings}
*
* @author Steve Ebersole
*/
class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
private final XMLManyToOneElement manyToOneElement;
private final LocalBindingContext bindingContext;
private final List<RelationalValueSource> valueSources;
ManyToOneAttributeSourceImpl(final XMLManyToOneElement manyToOneElement, LocalBindingContext bindingContext) {
this.manyToOneElement = manyToOneElement;
this.bindingContext = bindingContext;
this.valueSources = Helper.buildValueSources(
new Helper.ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return manyToOneElement.getColumn();
}
@Override
public String getFormulaAttribute() {
return manyToOneElement.getFormula();
}
@Override
public List getColumnOrFormulaElements() {
return manyToOneElement.getColumnOrFormula();
}
},
bindingContext
);
}
@Override
public String getName() {
return manyToOneElement.getName();
}
@Override
public ExplicitHibernateTypeSource getTypeInformation() {
return Helper.TO_ONE_ATTRIBUTE_TYPE_SOURCE;
}
@Override
public String getPropertyAccessorName() {
return manyToOneElement.getAccess();
}
@Override
public boolean isInsertable() {
return manyToOneElement.isInsert();
}
@Override
public boolean isUpdatable() {
return manyToOneElement.isUpdate();
}
@Override
public PropertyGeneration getGeneration() {
return PropertyGeneration.NEVER;
}
@Override
public boolean isLazy() {
return false;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return manyToOneElement.isOptimisticLock();
}
@Override
public Iterable<CascadeStyle> getCascadeStyle() {
return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext );
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.MANY_TO_ONE;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
public Iterable<MetaAttributeSource> metaAttributes() {
return Helper.buildMetaAttributeSources( manyToOneElement.getMeta() );
}
@Override
public String getReferencedEntityName() {
return manyToOneElement.getClazz() != null
? manyToOneElement.getClazz()
: manyToOneElement.getEntityName();
}
@Override
public String getReferencedEntityAttributeName() {
return manyToOneElement.getPropertyRef();
}
}

View File

@ -0,0 +1,161 @@
/*
* 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;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.binder.SingularAttributeSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLPropertyElement;
/**
* Implementation for {@code <property/>} mappings
*
* @author Steve Ebersole
*/
class PropertyAttributeSourceImpl implements SingularAttributeSource {
private final XMLPropertyElement propertyElement;
private final ExplicitHibernateTypeSource typeSource;
private final List<RelationalValueSource> valueSources;
PropertyAttributeSourceImpl(final XMLPropertyElement propertyElement, LocalBindingContext bindingContext) {
this.propertyElement = propertyElement;
this.typeSource = new ExplicitHibernateTypeSource() {
private final String name = propertyElement.getTypeAttribute() != null
? propertyElement.getTypeAttribute()
: propertyElement.getType() != null
? propertyElement.getType().getName()
: null;
private final Map<String, String> parameters = ( propertyElement.getType() != null )
? Helper.extractParameters( propertyElement.getType().getParam() )
: null;
@Override
public String getName() {
return name;
}
@Override
public Map<String, String> getParameters() {
return parameters;
}
};
this.valueSources = Helper.buildValueSources(
new Helper.ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return propertyElement.getColumn();
}
@Override
public String getFormulaAttribute() {
return propertyElement.getFormula();
}
@Override
public List getColumnOrFormulaElements() {
return propertyElement.getColumnOrFormula();
}
},
bindingContext
);
}
@Override
public String getName() {
return propertyElement.getName();
}
@Override
public ExplicitHibernateTypeSource getTypeInformation() {
return typeSource;
}
@Override
public String getPropertyAccessorName() {
return propertyElement.getAccess();
}
@Override
public boolean isInsertable() {
return Helper.getBooleanValue( propertyElement.isInsert(), true );
}
@Override
public boolean isUpdatable() {
return Helper.getBooleanValue( propertyElement.isUpdate(), true );
}
@Override
public PropertyGeneration getGeneration() {
return PropertyGeneration.parse( propertyElement.getGenerated() );
}
@Override
public boolean isLazy() {
return Helper.getBooleanValue( propertyElement.isLazy(), false );
}
@Override
public boolean isIncludedInOptimisticLocking() {
return Helper.getBooleanValue( propertyElement.isOptimisticLock(), true );
}
@Override
public Iterable<CascadeStyle> getCascadeStyle() {
return Helper.NO_CASCADING;
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.BASIC;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
public Iterable<MetaAttributeSource> metaAttributes() {
return Helper.buildMetaAttributeSources( propertyElement.getMeta() );
}
}

View File

@ -0,0 +1,178 @@
/*
* 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;
import org.hibernate.EntityMode;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.metamodel.binding.Caching;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.source.binder.IdentifierSource;
import org.hibernate.metamodel.source.binder.RootEntitySource;
import org.hibernate.metamodel.source.binder.SimpleIdentifierSource;
import org.hibernate.metamodel.source.binder.SingularAttributeSource;
import org.hibernate.metamodel.source.binder.TableSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLCacheElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping;
/**
* @author Steve Ebersole
*/
public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements RootEntitySource {
protected RootEntitySourceImpl(MappingDocument sourceMappingDocument, XMLHibernateMapping.XMLClass entityElement) {
super( sourceMappingDocument, entityElement );
}
@Override
protected XMLHibernateMapping.XMLClass entityElement() {
return (XMLHibernateMapping.XMLClass) super.entityElement();
}
@Override
public IdentifierSource getIdentifierSource() {
if ( entityElement().getId() != null ) {
return new SimpleIdentifierSource() {
@Override
public SingularAttributeSource getIdentifierAttributeSource() {
return new SingularIdentifierAttributeSourceImpl( entityElement().getId(), sourceMappingDocument().getMappingLocalBindingContext() );
}
@Override
public IdGenerator getIdentifierGeneratorDescriptor() {
if ( entityElement().getId().getGenerator() != null ) {
final String generatorName = entityElement().getId().getGenerator().getClazz();
IdGenerator idGenerator = sourceMappingDocument().getMappingLocalBindingContext()
.getMetadataImplementor()
.getIdGenerator( generatorName );
if ( idGenerator == null ) {
idGenerator = new IdGenerator(
getEntityName() + generatorName,
generatorName,
Helper.extractParameters( entityElement().getId().getGenerator().getParam() )
);
}
return idGenerator;
}
return null;
}
@Override
public Nature getNature() {
return Nature.SIMPLE;
}
};
}
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public SingularAttributeSource getVersioningAttributeSource() {
if ( entityElement().getVersion() != null ) {
return new VersionAttributeSourceImpl( entityElement().getVersion(), sourceMappingDocument().getMappingLocalBindingContext() );
}
else if ( entityElement().getTimestamp() != null ) {
return new TimestampAttributeSourceImpl( entityElement().getTimestamp(), sourceMappingDocument().getMappingLocalBindingContext() );
}
return null;
}
@Override
public SingularAttributeSource getDiscriminatorAttributeSource() {
// todo : implement
return null;
}
@Override
public EntityMode getEntityMode() {
return determineEntityMode();
}
@Override
public boolean isMutable() {
return entityElement().isMutable();
}
@Override
public boolean isExplicitPolymorphism() {
return "explicit".equals( entityElement().getPolymorphism() );
}
@Override
public String getWhere() {
return entityElement().getWhere();
}
@Override
public String getRowId() {
return entityElement().getRowid();
}
@Override
public OptimisticLockStyle getOptimisticLockStyle() {
final String optimisticLockModeString = Helper.getStringValue( entityElement().getOptimisticLock(), "version" );
try {
return OptimisticLockStyle.valueOf( optimisticLockModeString.toUpperCase() );
}
catch (Exception e) {
throw new MappingException(
"Unknown optimistic-lock value : " + optimisticLockModeString,
sourceMappingDocument().getOrigin()
);
}
}
@Override
public Caching getCaching() {
final XMLCacheElement cache = entityElement().getCache();
if ( cache == null ) {
return null;
}
final String region = cache.getRegion() != null ? cache.getRegion() : getEntityName();
final AccessType accessType = Enum.valueOf( AccessType.class, cache.getUsage() );
final boolean cacheLazyProps = !"non-lazy".equals( cache.getInclude() );
return new Caching( region, accessType, cacheLazyProps );
}
@Override
public TableSource getPrimaryTable() {
return new TableSource() {
@Override
public String getExplicitSchemaName() {
return entityElement().getSchema();
}
@Override
public String getExplicitCatalogName() {
return entityElement().getCatalog();
}
@Override
public String getExplicitTableName() {
return entityElement().getTable();
}
};
}
}

View File

@ -0,0 +1,165 @@
/*
* 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;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.binder.SingularAttributeSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping;
/**
* Implementation for {@code <id/>} mappings
*
* @author Steve Ebersole
*/
class SingularIdentifierAttributeSourceImpl implements SingularAttributeSource {
private final XMLHibernateMapping.XMLClass.XMLId idElement;
private final ExplicitHibernateTypeSource typeSource;
private final List<RelationalValueSource> valueSources;
public SingularIdentifierAttributeSourceImpl(
final XMLHibernateMapping.XMLClass.XMLId idElement,
LocalBindingContext bindingContext) {
this.idElement = idElement;
this.typeSource = new ExplicitHibernateTypeSource() {
private final String name = idElement.getTypeAttribute() != null
? idElement.getTypeAttribute()
: idElement.getType() != null
? idElement.getType().getName()
: null;
private final Map<String, String> parameters = ( idElement.getType() != null )
? Helper.extractParameters( idElement.getType().getParam() )
: null;
@Override
public String getName() {
return name;
}
@Override
public Map<String, String> getParameters() {
return parameters;
}
};
this.valueSources = Helper.buildValueSources(
new Helper.ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return idElement.getColumnAttribute();
}
@Override
public String getFormulaAttribute() {
return null;
}
@Override
public List getColumnOrFormulaElements() {
return idElement.getColumn();
}
},
bindingContext
);
}
@Override
public String getName() {
return idElement.getName() == null
? "id"
: idElement.getName();
}
@Override
public ExplicitHibernateTypeSource getTypeInformation() {
return typeSource;
}
@Override
public String getPropertyAccessorName() {
return idElement.getAccess();
}
@Override
public boolean isInsertable() {
return true;
}
@Override
public boolean isUpdatable() {
return false;
}
@Override
public PropertyGeneration getGeneration() {
return PropertyGeneration.INSERT;
}
@Override
public boolean isLazy() {
return false;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return false;
}
@Override
public Iterable<CascadeStyle> getCascadeStyle() {
return Helper.NO_CASCADING;
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.BASIC;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
public Iterable<MetaAttributeSource> metaAttributes() {
return Helper.buildMetaAttributeSources( idElement.getMeta() );
}
}

View File

@ -0,0 +1,80 @@
/*
* 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;
import org.hibernate.metamodel.source.binder.SubclassEntitySource;
import org.hibernate.metamodel.source.binder.TableSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLJoinedSubclassElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLUnionSubclassElement;
/**
* @author Steve Ebersole
*/
public class SubclassEntitySourceImpl extends AbstractEntitySourceImpl implements SubclassEntitySource {
protected SubclassEntitySourceImpl(MappingDocument sourceMappingDocument, EntityElement entityElement) {
super( sourceMappingDocument, entityElement );
}
@Override
public TableSource getPrimaryTable() {
if ( XMLJoinedSubclassElement.class.isInstance( entityElement() ) ) {
return new TableSource() {
@Override
public String getExplicitSchemaName() {
return ( (XMLJoinedSubclassElement) entityElement() ).getSchema();
}
@Override
public String getExplicitCatalogName() {
return ( (XMLJoinedSubclassElement) entityElement() ).getCatalog();
}
@Override
public String getExplicitTableName() {
return ( (XMLJoinedSubclassElement) entityElement() ).getTable();
}
};
}
else if ( XMLUnionSubclassElement.class.isInstance( entityElement() ) ) {
return new TableSource() {
@Override
public String getExplicitSchemaName() {
return ( (XMLUnionSubclassElement) entityElement() ).getSchema();
}
@Override
public String getExplicitCatalogName() {
return ( (XMLUnionSubclassElement) entityElement() ).getCatalog();
}
@Override
public String getExplicitTableName() {
return ( (XMLUnionSubclassElement) entityElement() ).getTable();
}
};
}
return null;
}
}

View File

@ -0,0 +1,176 @@
/*
* 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;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.internal.util.Value;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.binder.SingularAttributeSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping;
/**
* Implementation for {@code <timestamp/>} mappings
*
* @author Steve Ebersole
*/
class TimestampAttributeSourceImpl implements SingularAttributeSource {
private final XMLHibernateMapping.XMLClass.XMLTimestamp timestampElement;
private final LocalBindingContext bindingContext;
private final List<RelationalValueSource> valueSources;
TimestampAttributeSourceImpl(
final XMLHibernateMapping.XMLClass.XMLTimestamp timestampElement,
LocalBindingContext bindingContext) {
this.timestampElement = timestampElement;
this.bindingContext = bindingContext;
this.valueSources = Helper.buildValueSources(
new Helper.ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return timestampElement.getColumn();
}
@Override
public String getFormulaAttribute() {
return null;
}
@Override
public List getColumnOrFormulaElements() {
return null;
}
},
bindingContext
);
}
private final ExplicitHibernateTypeSource typeSource = new ExplicitHibernateTypeSource() {
@Override
public String getName() {
return "db".equals( timestampElement.getSource() ) ? "dbtimestamp" : "timestamp";
}
@Override
public Map<String, String> getParameters() {
return null;
}
};
@Override
public String getName() {
return timestampElement.getName();
}
@Override
public ExplicitHibernateTypeSource getTypeInformation() {
return typeSource;
}
@Override
public String getPropertyAccessorName() {
return timestampElement.getAccess();
}
@Override
public boolean isInsertable() {
return true;
}
@Override
public boolean isUpdatable() {
return true;
}
private Value<PropertyGeneration> propertyGenerationValue = new Value<PropertyGeneration>(
new Value.DeferredInitializer<PropertyGeneration>() {
@Override
public PropertyGeneration initialize() {
final PropertyGeneration propertyGeneration = timestampElement.getGenerated() == null
? PropertyGeneration.NEVER
: PropertyGeneration.parse( timestampElement.getGenerated().value() );
if ( propertyGeneration == PropertyGeneration.INSERT ) {
throw new MappingException(
"'generated' attribute cannot be 'insert' for versioning property",
bindingContext.getOrigin()
);
}
return propertyGeneration;
}
}
);
@Override
public PropertyGeneration getGeneration() {
return propertyGenerationValue.getValue();
}
@Override
public boolean isLazy() {
return false;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return false;
}
@Override
public Iterable<CascadeStyle> getCascadeStyle() {
return Helper.NO_CASCADING;
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.BASIC;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
public Iterable<MetaAttributeSource> metaAttributes() {
return Helper.buildMetaAttributeSources( timestampElement.getMeta() );
}
}

View File

@ -0,0 +1,176 @@
/*
* 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;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.internal.util.Value;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.binder.SingularAttributeSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLHibernateMapping;
/**
* Implementation for {@code <version/>} mappings
*
* @author Steve Ebersole
*/
class VersionAttributeSourceImpl implements SingularAttributeSource {
private final XMLHibernateMapping.XMLClass.XMLVersion versionElement;
private final LocalBindingContext bindingContext;
private final List<RelationalValueSource> valueSources;
VersionAttributeSourceImpl(
final XMLHibernateMapping.XMLClass.XMLVersion versionElement,
LocalBindingContext bindingContext) {
this.versionElement = versionElement;
this.bindingContext = bindingContext;
this.valueSources = Helper.buildValueSources(
new Helper.ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return versionElement.getColumnAttribute();
}
@Override
public String getFormulaAttribute() {
return null;
}
@Override
public List getColumnOrFormulaElements() {
return versionElement.getColumn();
}
},
bindingContext
);
}
private final ExplicitHibernateTypeSource typeSource = new ExplicitHibernateTypeSource() {
@Override
public String getName() {
return versionElement.getType() == null ? "integer" : versionElement.getType();
}
@Override
public Map<String, String> getParameters() {
return null;
}
};
@Override
public String getName() {
return versionElement.getName();
}
@Override
public ExplicitHibernateTypeSource getTypeInformation() {
return typeSource;
}
@Override
public String getPropertyAccessorName() {
return versionElement.getAccess();
}
@Override
public boolean isInsertable() {
return Helper.getBooleanValue( versionElement.isInsert(), true );
}
@Override
public boolean isUpdatable() {
return true;
}
private Value<PropertyGeneration> propertyGenerationValue = new Value<PropertyGeneration>(
new Value.DeferredInitializer<PropertyGeneration>() {
@Override
public PropertyGeneration initialize() {
final PropertyGeneration propertyGeneration = versionElement.getGenerated() == null
? PropertyGeneration.NEVER
: PropertyGeneration.parse( versionElement.getGenerated().value() );
if ( propertyGeneration == PropertyGeneration.INSERT ) {
throw new MappingException(
"'generated' attribute cannot be 'insert' for versioning property",
bindingContext.getOrigin()
);
}
return propertyGeneration;
}
}
);
@Override
public PropertyGeneration getGeneration() {
return propertyGenerationValue.getValue();
}
@Override
public boolean isLazy() {
return false;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return false;
}
@Override
public Iterable<CascadeStyle> getCascadeStyle() {
return Helper.NO_CASCADING;
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.BASIC;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
public Iterable<MetaAttributeSource> metaAttributes() {
return Helper.buildMetaAttributeSources( versionElement.getMeta() );
}
}

View File

@ -364,6 +364,11 @@ public Class<?> initialize() {
);
}
@Override
public String qualifyClassName(String name) {
return name;
}
@Override
public Database getDatabase() {
return database;

View File

@ -56,7 +56,6 @@ public void testBasicMiddleOutBuilding() {
Table table = new Table( new Schema( null, null ), "the_table" );
Entity entity = new Entity( "TheEntity", "NoSuchClass", makeJavaType( "NoSuchClass" ), null );
EntityBinding entityBinding = new EntityBinding();
entityBinding.setRoot( true );
entityBinding.setEntity( entity );
entityBinding.setBaseTable( table );

View File

@ -101,6 +101,11 @@ public Value<Class<?>> makeClassReference(String className) {
throw new NotYetImplementedException();
}
@Override
public String qualifyClassName(String name) {
return name;
}
@Override
public ClassInfo getClassInfo(String name) {
DotName dotName = DotName.createSimple( name );