HHH-7088 - Implement secondary table support in new metamodel code
This commit is contained in:
parent
b6902ad211
commit
f76524786c
|
@ -58,6 +58,7 @@ import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding;
|
|||
import org.hibernate.metamodel.spi.binding.MetaAttribute;
|
||||
import org.hibernate.metamodel.spi.binding.PluralAttributeElementNature;
|
||||
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
|
||||
import org.hibernate.metamodel.spi.binding.SecondaryTable;
|
||||
import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.domain.Attribute;
|
||||
|
@ -96,6 +97,7 @@ import org.hibernate.metamodel.spi.source.Orderable;
|
|||
import org.hibernate.metamodel.spi.source.PluralAttributeElementSource;
|
||||
import org.hibernate.metamodel.spi.source.PluralAttributeNature;
|
||||
import org.hibernate.metamodel.spi.source.PluralAttributeSource;
|
||||
import org.hibernate.metamodel.spi.source.PrimaryKeyJoinColumnSource;
|
||||
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
||||
import org.hibernate.metamodel.spi.source.RelationalValueSourceContainer;
|
||||
import org.hibernate.metamodel.spi.source.RootEntitySource;
|
||||
|
@ -1348,10 +1350,13 @@ public class Binder {
|
|||
}
|
||||
|
||||
private void bindSecondaryTables(EntitySource entitySource, EntityBinding entityBinding) {
|
||||
final TableSpecification primaryEntityTable = entityBinding.getPrimaryTable();
|
||||
|
||||
for ( SecondaryTableSource secondaryTableSource : entitySource.getSecondaryTables() ) {
|
||||
final TableSpecification secondaryTable;
|
||||
final TableSpecificationSource source = secondaryTableSource.getTableSource();
|
||||
if ( TableSource.class.isInstance( source ) ) {
|
||||
final Table table = createTable(
|
||||
secondaryTable = createTable(
|
||||
(TableSource) source,
|
||||
new InferredNamingStrategy() {
|
||||
@Override
|
||||
|
@ -1363,12 +1368,52 @@ public class Binder {
|
|||
}
|
||||
}
|
||||
);
|
||||
// todo : finish up...
|
||||
// 1) no need to keep secondary tables on EntityBinding because we should be able to look them
|
||||
// up from Schema
|
||||
// 2) process foreign key
|
||||
entityBinding.addSecondaryTable( table.getLogicalName().getName(), table );
|
||||
}
|
||||
else {
|
||||
secondaryTable = createInLineView( (InLineViewSource) source );
|
||||
}
|
||||
|
||||
// todo : really need a concept like SecondaryTableSource in the binding model as well
|
||||
// so that EntityBinding can know the proper foreign key to use to build SQL statements.
|
||||
|
||||
ForeignKey foreignKey = null;
|
||||
if ( secondaryTableSource.getForeignKeyName() != null ) {
|
||||
foreignKey = secondaryTable.locateForeignKey( secondaryTableSource.getForeignKeyName() );
|
||||
if ( foreignKey == null ) {
|
||||
foreignKey = secondaryTable.createForeignKey(
|
||||
primaryEntityTable,
|
||||
secondaryTableSource.getForeignKeyName()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// for now lets assume we have to create it, but eventually we should look through the
|
||||
// candidate foreign keys referencing primary table also...
|
||||
foreignKey = secondaryTable.createForeignKey( primaryEntityTable, null );
|
||||
}
|
||||
|
||||
for ( PrimaryKeyJoinColumnSource joinColumnSource : secondaryTableSource.getJoinColumns() ) {
|
||||
// todo : currently we only support columns here, not formulas
|
||||
// todo : apply naming strategy to infer missing column name
|
||||
Column fkColumn = secondaryTable.locateColumn( joinColumnSource.getColumnName() );
|
||||
if ( fkColumn == null ) {
|
||||
fkColumn = secondaryTable.createColumn( joinColumnSource.getColumnName() );
|
||||
if ( joinColumnSource.getColumnDefinition() != null ) {
|
||||
fkColumn.setSqlType( joinColumnSource.getColumnDefinition() );
|
||||
}
|
||||
}
|
||||
if ( joinColumnSource.getReferencedColumnName() != null ) {
|
||||
final Column referencedColumn = primaryEntityTable.locateColumn(
|
||||
joinColumnSource.getReferencedColumnName()
|
||||
);
|
||||
foreignKey.addColumnMapping( fkColumn, referencedColumn );
|
||||
}
|
||||
else {
|
||||
foreignKey.addColumn( fkColumn );
|
||||
}
|
||||
}
|
||||
|
||||
entityBinding.addSecondaryTable( new SecondaryTable( secondaryTable, foreignKey ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,28 +63,158 @@ import org.hibernate.metamodel.spi.source.SubclassEntitySource;
|
|||
* @author Steve Ebersole
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public abstract class AbstractEntitySourceImpl implements EntitySource {
|
||||
private final MappingDocument sourceMappingDocument;
|
||||
public abstract class AbstractEntitySourceImpl
|
||||
extends AbstractHbmSourceNode
|
||||
implements EntitySource, Helper.InLineViewNameInferrer {
|
||||
private final EntityElement entityElement;
|
||||
private final Set<SecondaryTableSource> secondaryTableSources;
|
||||
private final String className;
|
||||
private final String entityName;
|
||||
|
||||
private List<SubclassEntitySource> subclassEntitySources = new ArrayList<SubclassEntitySource>();
|
||||
private int inLineViewCount = 0;
|
||||
|
||||
// logically final, but built during 'afterInstantiation' callback
|
||||
private List<AttributeSource> attributeSources;
|
||||
private Set<SecondaryTableSource> secondaryTableSources;
|
||||
private List<SubclassEntitySource> subclassEntitySources;
|
||||
|
||||
protected AbstractEntitySourceImpl(MappingDocument sourceMappingDocument, EntityElement entityElement) {
|
||||
this.sourceMappingDocument = sourceMappingDocument;
|
||||
super( sourceMappingDocument );
|
||||
this.entityElement = entityElement;
|
||||
|
||||
secondaryTableSources = extractSecondaryTables( entityElement, sourceMappingDocument.getMappingLocalBindingContext() );
|
||||
this.className = bindingContext().qualifyClassName( entityElement.getName() );
|
||||
this.entityName = StringHelper.isNotEmpty( entityElement.getEntityName() )
|
||||
? entityElement.getEntityName()
|
||||
: className;
|
||||
}
|
||||
|
||||
private static Set<SecondaryTableSource> extractSecondaryTables(EntityElement entityElement, HbmBindingContext bindingContext) {
|
||||
@Override
|
||||
public String inferInLineViewName() {
|
||||
return entityName + '#' + (++inLineViewCount);
|
||||
}
|
||||
|
||||
protected void afterInstantiation() {
|
||||
this.attributeSources = buildAttributeSources();
|
||||
this.secondaryTableSources = buildSecondaryTables();
|
||||
|
||||
this.subclassEntitySources = buildSubClassSources();
|
||||
}
|
||||
|
||||
protected List<AttributeSource> buildAttributeSources() {
|
||||
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
|
||||
buildAttributeSources( attributeSources );
|
||||
return attributeSources;
|
||||
}
|
||||
|
||||
protected List<AttributeSource> buildAttributeSources(List<AttributeSource> attributeSources) {
|
||||
processAttributes(
|
||||
attributeSources,
|
||||
entityElement.getPropertyOrManyToOneOrOneToOne(),
|
||||
null,
|
||||
SingularAttributeSource.NaturalIdMutability.NOT_NATURAL_ID
|
||||
);
|
||||
return attributeSources;
|
||||
}
|
||||
|
||||
protected void processAttributes(
|
||||
List<AttributeSource> results,
|
||||
List attributeElements,
|
||||
String logicalTableName,
|
||||
SingularAttributeSource.NaturalIdMutability naturalIdMutability) {
|
||||
for ( Object attributeElement : attributeElements ) {
|
||||
if ( JaxbPropertyElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new PropertyAttributeSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
JaxbPropertyElement.class.cast( attributeElement ),
|
||||
logicalTableName,
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbComponentElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new ComponentAttributeSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
(JaxbComponentElement) attributeElement,
|
||||
this,
|
||||
logicalTableName,
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbManyToOneElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new ManyToOneAttributeSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
JaxbManyToOneElement.class.cast( attributeElement ),
|
||||
logicalTableName,
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbOneToOneElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbAnyElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbBagElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new BagAttributeSourceImpl(
|
||||
JaxbBagElement.class.cast( attributeElement ),
|
||||
this
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbIdbagElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbSetElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new SetAttributeSourceImpl(
|
||||
JaxbSetElement.class.cast( attributeElement ),
|
||||
this
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbListElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbMapElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else {
|
||||
throw new AssertionFailure( "Unexpected attribute element type encountered : " + attributeElement.getClass() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected List<SubclassEntitySource> buildSubClassSources() {
|
||||
// todo : implement subclass processing
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private Set<SecondaryTableSource> buildSecondaryTables() {
|
||||
if ( ! JoinElementSource.class.isInstance( entityElement ) ) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
final Set<SecondaryTableSource> secondaryTableSources = new HashSet<SecondaryTableSource>();
|
||||
for ( JaxbJoinElement joinElement : ( (JoinElementSource) entityElement ).getJoin() ) {
|
||||
secondaryTableSources.add( new SecondaryTableSourceImpl( joinElement, bindingContext ) );
|
||||
final SecondaryTableSourceImpl secondaryTableSource = new SecondaryTableSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
joinElement,
|
||||
this
|
||||
);
|
||||
secondaryTableSources.add( secondaryTableSource );
|
||||
|
||||
final String logicalTableName = secondaryTableSource.getLogicalTableNameForContainedColumns();
|
||||
processAttributes(
|
||||
attributeSources,
|
||||
joinElement.getPropertyOrManyToOneOrComponent(),
|
||||
logicalTableName,
|
||||
SingularAttributeSource.NaturalIdMutability.NOT_NATURAL_ID
|
||||
);
|
||||
}
|
||||
return secondaryTableSources;
|
||||
}
|
||||
|
@ -93,30 +223,24 @@ public abstract class AbstractEntitySourceImpl implements EntitySource {
|
|||
return entityElement;
|
||||
}
|
||||
|
||||
protected MappingDocument sourceMappingDocument() {
|
||||
return sourceMappingDocument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Origin getOrigin() {
|
||||
return sourceMappingDocument.getOrigin();
|
||||
return origin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalBindingContext getLocalBindingContext() {
|
||||
return sourceMappingDocument.getMappingLocalBindingContext();
|
||||
return bindingContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityName() {
|
||||
return StringHelper.isNotEmpty( entityElement.getEntityName() )
|
||||
? entityElement.getEntityName()
|
||||
: getClassName();
|
||||
return entityName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return getLocalBindingContext().qualifyClassName( entityElement.getName() );
|
||||
return className;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -218,95 +342,14 @@ public abstract class AbstractEntitySourceImpl implements EntitySource {
|
|||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return sourceMappingDocument.getMappingLocalBindingContext().determineEntityName( entityElement );
|
||||
return bindingContext().determineEntityName( entityElement );
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AttributeSource> attributeSources() {
|
||||
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
|
||||
processAttributes( attributeSources );
|
||||
return attributeSources;
|
||||
}
|
||||
|
||||
protected List<AttributeSource> processAttributes(List<AttributeSource> attributeSources) {
|
||||
processAttributes(
|
||||
attributeSources,
|
||||
entityElement.getPropertyOrManyToOneOrOneToOne(),
|
||||
SingularAttributeSource.NaturalIdMutability.NOT_NATURAL_ID
|
||||
);
|
||||
return attributeSources;
|
||||
}
|
||||
|
||||
protected void processAttributes(
|
||||
List<AttributeSource> results,
|
||||
List attributeElements,
|
||||
SingularAttributeSource.NaturalIdMutability naturalIdMutability) {
|
||||
for ( Object attributeElement : attributeElements ) {
|
||||
if ( JaxbPropertyElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new PropertyAttributeSourceImpl(
|
||||
JaxbPropertyElement.class.cast( attributeElement ),
|
||||
sourceMappingDocument().getMappingLocalBindingContext(),
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbComponentElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new ComponentAttributeSourceImpl(
|
||||
(JaxbComponentElement) attributeElement,
|
||||
this,
|
||||
sourceMappingDocument.getMappingLocalBindingContext(),
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbManyToOneElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new ManyToOneAttributeSourceImpl(
|
||||
JaxbManyToOneElement.class.cast( attributeElement ),
|
||||
sourceMappingDocument().getMappingLocalBindingContext(),
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbOneToOneElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbAnyElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbBagElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new BagAttributeSourceImpl(
|
||||
JaxbBagElement.class.cast( attributeElement ),
|
||||
this
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbIdbagElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbSetElement.class.isInstance( attributeElement ) ) {
|
||||
results.add(
|
||||
new SetAttributeSourceImpl(
|
||||
JaxbSetElement.class.cast( attributeElement ),
|
||||
this
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbListElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbMapElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else {
|
||||
throw new AssertionFailure( "Unexpected attribute element type encountered : " + attributeElement.getClass() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EntityHierarchyImpl entityHierarchy;
|
||||
|
||||
public void injectHierarchy(EntityHierarchyImpl entityHierarchy) {
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, 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.internal.source.hbm;
|
||||
|
||||
import org.hibernate.internal.jaxb.JaxbRoot;
|
||||
import org.hibernate.internal.jaxb.Origin;
|
||||
import org.hibernate.internal.jaxb.mapping.hbm.JaxbHibernateMapping;
|
||||
import org.hibernate.internal.util.Value;
|
||||
import org.hibernate.metamodel.spi.source.MappingException;
|
||||
|
||||
/**
|
||||
* Base class for any and all source objects coming from {@code hbm.xml} parsing. Defines standard access
|
||||
* back to the {@link MappingDocument} object and the services it provides (namely access to
|
||||
* {@link HbmBindingContext}).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractHbmSourceNode {
|
||||
private final MappingDocument sourceMappingDocument;
|
||||
|
||||
protected AbstractHbmSourceNode(MappingDocument sourceMappingDocument) {
|
||||
this.sourceMappingDocument = sourceMappingDocument;
|
||||
}
|
||||
|
||||
protected MappingDocument sourceMappingDocument() {
|
||||
return sourceMappingDocument;
|
||||
}
|
||||
|
||||
protected HbmBindingContext bindingContext() {
|
||||
return sourceMappingDocument().getMappingLocalBindingContext();
|
||||
}
|
||||
|
||||
protected Origin origin() {
|
||||
return sourceMappingDocument().getOrigin();
|
||||
}
|
||||
|
||||
protected JaxbRoot<JaxbHibernateMapping> mappingRoot() {
|
||||
return sourceMappingDocument().getJaxbRoot();
|
||||
}
|
||||
|
||||
protected Value<Class<?>> makeClassReference(String className) {
|
||||
return bindingContext().makeClassReference( bindingContext().qualifyClassName( className ) );
|
||||
}
|
||||
|
||||
protected MappingException makeMappingException(String message) {
|
||||
return bindingContext().makeMappingException( message );
|
||||
}
|
||||
|
||||
protected MappingException makeMappingException(String message, Exception cause) {
|
||||
return bindingContext().makeMappingException( message, cause );
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ import org.hibernate.metamodel.spi.source.TableSpecificationSource;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractPluralAttributeSourceImpl
|
||||
implements PluralAttributeSource {
|
||||
implements PluralAttributeSource, Helper.InLineViewNameInferrer {
|
||||
private final PluralAttributeElement pluralAttributeElement;
|
||||
private final AttributeSourceContainer container;
|
||||
|
||||
|
@ -140,12 +140,14 @@ public abstract class AbstractPluralAttributeSourceImpl
|
|||
return elementSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String inferInLineViewName() {
|
||||
return container().getPath() + "." + pluralAttributeElement.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecificationSource getCollectionTableSpecificationSource() {
|
||||
return Helper.createTableSource(
|
||||
pluralAttributeElement,
|
||||
container().getPath() + "." + pluralAttributeElement.getName()
|
||||
);
|
||||
return Helper.createTableSource( pluralAttributeElement, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -46,30 +46,82 @@ import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
|
|||
import org.hibernate.metamodel.spi.source.MetaAttributeSource;
|
||||
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
||||
import org.hibernate.metamodel.spi.source.SingularAttributeNature;
|
||||
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ComponentAttributeSourceImpl implements ComponentAttributeSource {
|
||||
class ComponentAttributeSourceImpl extends AbstractHbmSourceNode implements ComponentAttributeSource {
|
||||
private final JaxbComponentElement componentElement;
|
||||
private final AttributeSourceContainer parentContainer;
|
||||
private final List<AttributeSource> subAttributeSources;
|
||||
private final NaturalIdMutability naturalIdMutability;
|
||||
private final Value<Class<?>> componentClassReference;
|
||||
private final String path;
|
||||
|
||||
public ComponentAttributeSourceImpl(
|
||||
MappingDocument sourceMappingDocument,
|
||||
JaxbComponentElement componentElement,
|
||||
AttributeSourceContainer parentContainer,
|
||||
LocalBindingContext bindingContext,
|
||||
String logicalTableName,
|
||||
NaturalIdMutability naturalIdMutability) {
|
||||
super( sourceMappingDocument );
|
||||
this.componentElement = componentElement;
|
||||
this.parentContainer = parentContainer;
|
||||
this.naturalIdMutability = naturalIdMutability;
|
||||
this.componentClassReference = bindingContext.makeClassReference(
|
||||
bindingContext.qualifyClassName( componentElement.getClazz() )
|
||||
);
|
||||
this.componentClassReference = makeClassReference( componentElement.getClazz() );
|
||||
this.path = parentContainer.getPath() + '.' + componentElement.getName();
|
||||
|
||||
this.subAttributeSources = buildAttributeSources( logicalTableName );
|
||||
}
|
||||
|
||||
private List<AttributeSource> buildAttributeSources(String logicalTableName) {
|
||||
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
|
||||
for ( Object attributeElement : componentElement.getPropertyOrManyToOneOrOneToOne() ) {
|
||||
if ( JaxbPropertyElement.class.isInstance( attributeElement ) ) {
|
||||
attributeSources.add(
|
||||
new PropertyAttributeSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
JaxbPropertyElement.class.cast( attributeElement ),
|
||||
logicalTableName,
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbComponentElement.class.isInstance( attributeElement ) ) {
|
||||
attributeSources.add(
|
||||
new ComponentAttributeSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
(JaxbComponentElement) attributeElement,
|
||||
this,
|
||||
logicalTableName,
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbManyToOneElement.class.isInstance( attributeElement ) ) {
|
||||
attributeSources.add(
|
||||
new ManyToOneAttributeSourceImpl(
|
||||
sourceMappingDocument(),
|
||||
JaxbManyToOneElement.class.cast( attributeElement ),
|
||||
logicalTableName,
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbOneToOneElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbAnyElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbOneToManyElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbManyToManyElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
}
|
||||
return attributeSources;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -113,50 +165,7 @@ public class ComponentAttributeSourceImpl implements ComponentAttributeSource {
|
|||
|
||||
@Override
|
||||
public List<AttributeSource> attributeSources() {
|
||||
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
|
||||
for ( Object attributeElement : componentElement.getPropertyOrManyToOneOrOneToOne() ) {
|
||||
if ( JaxbPropertyElement.class.isInstance( attributeElement ) ) {
|
||||
attributeSources.add(
|
||||
new PropertyAttributeSourceImpl(
|
||||
JaxbPropertyElement.class.cast( attributeElement ),
|
||||
getLocalBindingContext(),
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbComponentElement.class.isInstance( attributeElement ) ) {
|
||||
attributeSources.add(
|
||||
new ComponentAttributeSourceImpl(
|
||||
(JaxbComponentElement) attributeElement,
|
||||
this,
|
||||
getLocalBindingContext(),
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbManyToOneElement.class.isInstance( attributeElement ) ) {
|
||||
attributeSources.add(
|
||||
new ManyToOneAttributeSourceImpl(
|
||||
JaxbManyToOneElement.class.cast( attributeElement ),
|
||||
getLocalBindingContext(),
|
||||
naturalIdMutability
|
||||
)
|
||||
);
|
||||
}
|
||||
else if ( JaxbOneToOneElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbAnyElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbOneToManyElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
else if ( JaxbManyToManyElement.class.isInstance( attributeElement ) ) {
|
||||
// todo : implement
|
||||
}
|
||||
}
|
||||
return attributeSources;
|
||||
return subAttributeSources;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -289,7 +289,13 @@ public class Helper {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static TableSpecificationSource createTableSource(TableInformationSource jaxbTableSource, String context) {
|
||||
public static interface InLineViewNameInferrer {
|
||||
public String inferInLineViewName();
|
||||
}
|
||||
|
||||
public static TableSpecificationSource createTableSource(
|
||||
TableInformationSource jaxbTableSource,
|
||||
InLineViewNameInferrer inLineViewNameInferrer) {
|
||||
if ( jaxbTableSource.getSubselectAttribute() == null && jaxbTableSource.getSubselect() == null ) {
|
||||
return new TableSourceImpl(
|
||||
jaxbTableSource.getSchema(),
|
||||
|
@ -304,7 +310,9 @@ public class Helper {
|
|||
jaxbTableSource.getSubselectAttribute() != null
|
||||
? jaxbTableSource.getSubselectAttribute()
|
||||
: jaxbTableSource.getSubselect(),
|
||||
context
|
||||
jaxbTableSource.getTable() == null
|
||||
? inLineViewNameInferrer.inferInLineViewName()
|
||||
: jaxbTableSource.getTable()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.hibernate.engine.spi.CascadeStyle;
|
|||
import org.hibernate.internal.jaxb.mapping.hbm.JaxbManyToOneElement;
|
||||
import org.hibernate.mapping.PropertyGeneration;
|
||||
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
|
||||
import org.hibernate.metamodel.spi.source.LocalBindingContext;
|
||||
import org.hibernate.metamodel.spi.source.MappingException;
|
||||
import org.hibernate.metamodel.spi.source.MetaAttributeSource;
|
||||
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
||||
|
@ -44,18 +43,18 @@ import org.hibernate.metamodel.spi.source.ToOneAttributeSource;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
|
||||
class ManyToOneAttributeSourceImpl extends AbstractHbmSourceNode implements ToOneAttributeSource {
|
||||
private final JaxbManyToOneElement manyToOneElement;
|
||||
private final LocalBindingContext bindingContext;
|
||||
private final NaturalIdMutability naturalIdMutability;
|
||||
private final List<RelationalValueSource> valueSources;
|
||||
|
||||
ManyToOneAttributeSourceImpl(
|
||||
MappingDocument sourceMappingDocument,
|
||||
final JaxbManyToOneElement manyToOneElement,
|
||||
LocalBindingContext bindingContext,
|
||||
final String logicalTableName,
|
||||
NaturalIdMutability naturalIdMutability) {
|
||||
super( sourceMappingDocument );
|
||||
this.manyToOneElement = manyToOneElement;
|
||||
this.bindingContext = bindingContext;
|
||||
this.naturalIdMutability = naturalIdMutability;
|
||||
this.valueSources = Helper.buildValueSources(
|
||||
new Helper.ValueSourcesAdapter() {
|
||||
|
@ -76,8 +75,7 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
|
|||
|
||||
@Override
|
||||
public String getContainingTableName() {
|
||||
// todo : need to implement this...
|
||||
return null;
|
||||
return logicalTableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -90,7 +88,7 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
|
|||
return manyToOneElement.isUpdate();
|
||||
}
|
||||
},
|
||||
bindingContext
|
||||
bindingContext()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -131,7 +129,7 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
|
|||
|
||||
@Override
|
||||
public Iterable<CascadeStyle> getCascadeStyles() {
|
||||
return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext );
|
||||
return Helper.interpretCascadeStyles( manyToOneElement.getCascade(), bindingContext() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -154,7 +152,7 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
|
|||
return FetchTiming.DELAYED;
|
||||
}
|
||||
else {
|
||||
return bindingContext.getMappingDefaults().areAssociationsLazy()
|
||||
return bindingContext().getMappingDefaults().areAssociationsLazy()
|
||||
? FetchTiming.DELAYED
|
||||
: FetchTiming.IMMEDIATE;
|
||||
}
|
||||
|
@ -175,7 +173,7 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
|
|||
lazySelection,
|
||||
manyToOneElement.getName()
|
||||
),
|
||||
bindingContext.getOrigin()
|
||||
origin()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -196,7 +194,7 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
|
|||
}
|
||||
else {
|
||||
if ( "auto".equals( outerJoinSelection ) ) {
|
||||
return bindingContext.getMappingDefaults().areAssociationsLazy()
|
||||
return bindingContext().getMappingDefaults().areAssociationsLazy()
|
||||
? FetchStyle.SELECT
|
||||
: FetchStyle.JOIN;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.util.Map;
|
|||
import org.hibernate.internal.jaxb.mapping.hbm.JaxbPropertyElement;
|
||||
import org.hibernate.mapping.PropertyGeneration;
|
||||
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
|
||||
import org.hibernate.metamodel.spi.source.LocalBindingContext;
|
||||
import org.hibernate.metamodel.spi.source.MetaAttributeSource;
|
||||
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
||||
import org.hibernate.metamodel.spi.source.SingularAttributeNature;
|
||||
|
@ -40,16 +39,18 @@ import org.hibernate.metamodel.spi.source.SingularAttributeSource;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class PropertyAttributeSourceImpl implements SingularAttributeSource {
|
||||
class PropertyAttributeSourceImpl extends AbstractHbmSourceNode implements SingularAttributeSource {
|
||||
private final JaxbPropertyElement propertyElement;
|
||||
private final ExplicitHibernateTypeSource typeSource;
|
||||
private final List<RelationalValueSource> valueSources;
|
||||
private final NaturalIdMutability naturalIdMutability;
|
||||
|
||||
PropertyAttributeSourceImpl(
|
||||
MappingDocument sourceMappingDocument,
|
||||
final JaxbPropertyElement propertyElement,
|
||||
LocalBindingContext bindingContext,
|
||||
final String logicalTableName,
|
||||
NaturalIdMutability naturalIdMutability) {
|
||||
super( sourceMappingDocument );
|
||||
this.propertyElement = propertyElement;
|
||||
this.typeSource = new ExplicitHibernateTypeSource() {
|
||||
private final String name = propertyElement.getTypeAttribute() != null
|
||||
|
@ -90,8 +91,7 @@ class PropertyAttributeSourceImpl implements SingularAttributeSource {
|
|||
|
||||
@Override
|
||||
public String getContainingTableName() {
|
||||
// todo : need to implement this...
|
||||
return null;
|
||||
return logicalTableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,7 +104,7 @@ class PropertyAttributeSourceImpl implements SingularAttributeSource {
|
|||
return Helper.getBooleanValue( propertyElement.isUpdate(), true );
|
||||
}
|
||||
},
|
||||
bindingContext
|
||||
bindingContext()
|
||||
);
|
||||
this.naturalIdMutability = naturalIdMutability;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.internal.source.hbm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
|
@ -44,6 +43,7 @@ import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
|||
import org.hibernate.metamodel.spi.source.RootEntitySource;
|
||||
import org.hibernate.metamodel.spi.source.SimpleIdentifierSource;
|
||||
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
|
||||
import org.hibernate.metamodel.spi.source.SubclassEntitySource;
|
||||
import org.hibernate.metamodel.spi.source.TableSpecificationSource;
|
||||
import org.hibernate.metamodel.spi.source.VersionAttributeSource;
|
||||
|
||||
|
@ -57,10 +57,9 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
|
|||
MappingDocument sourceMappingDocument,
|
||||
JaxbHibernateMapping.JaxbClass entityElement) {
|
||||
super( sourceMappingDocument, entityElement );
|
||||
this.primaryTable = Helper.createTableSource(
|
||||
entityElement,
|
||||
sourceMappingDocument.getMappingLocalBindingContext().determineEntityName( entityElement )
|
||||
);
|
||||
this.primaryTable = Helper.createTableSource( entityElement, this );
|
||||
|
||||
afterInstantiation();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -126,20 +125,19 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<AttributeSource> attributeSources() {
|
||||
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
|
||||
protected List<AttributeSource> buildAttributeSources(List<AttributeSource> attributeSources) {
|
||||
final JaxbHibernateMapping.JaxbClass.JaxbNaturalId naturalId = entityElement().getNaturalId();
|
||||
if ( naturalId != null ) {
|
||||
processAttributes(
|
||||
attributeSources,
|
||||
naturalId.getPropertyOrManyToOneOrComponent(),
|
||||
null,
|
||||
naturalId.isMutable()
|
||||
? SingularAttributeSource.NaturalIdMutability.MUTABLE
|
||||
: SingularAttributeSource.NaturalIdMutability.IMMUTABLE
|
||||
);
|
||||
}
|
||||
processAttributes( attributeSources );
|
||||
return attributeSources;
|
||||
return super.buildAttributeSources( attributeSources );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,7 +150,6 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
|
|||
return entityElement().isMutable();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isExplicitPolymorphism() {
|
||||
return "explicit".equals( entityElement().getPolymorphism() );
|
||||
|
|
|
@ -28,30 +28,32 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.internal.jaxb.mapping.hbm.JaxbColumnElement;
|
||||
import org.hibernate.internal.jaxb.mapping.hbm.JaxbJoinElement;
|
||||
import org.hibernate.metamodel.spi.source.InLineViewSource;
|
||||
import org.hibernate.metamodel.spi.source.PrimaryKeyJoinColumnSource;
|
||||
import org.hibernate.metamodel.spi.source.SecondaryTableSource;
|
||||
import org.hibernate.metamodel.spi.source.TableSource;
|
||||
import org.hibernate.metamodel.spi.source.TableSpecificationSource;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SecondaryTableSourceImpl implements SecondaryTableSource {
|
||||
class SecondaryTableSourceImpl extends AbstractHbmSourceNode implements SecondaryTableSource {
|
||||
private final JaxbJoinElement joinElement;
|
||||
private final TableSpecificationSource joinTable;
|
||||
private final List<PrimaryKeyJoinColumnSource> joinColumns;
|
||||
|
||||
public SecondaryTableSourceImpl(JaxbJoinElement joinElement, HbmBindingContext bindingContext) {
|
||||
public SecondaryTableSourceImpl(
|
||||
MappingDocument sourceMappingDocument,
|
||||
JaxbJoinElement joinElement,
|
||||
Helper.InLineViewNameInferrer inLineViewNameInferrer) {
|
||||
super( sourceMappingDocument );
|
||||
this.joinElement = joinElement;
|
||||
this.joinTable = Helper.createTableSource(
|
||||
joinElement,
|
||||
// todo : need to implement this
|
||||
null
|
||||
);
|
||||
this.joinTable = Helper.createTableSource( joinElement, inLineViewNameInferrer );
|
||||
|
||||
joinColumns = new ArrayList<PrimaryKeyJoinColumnSource>();
|
||||
if ( joinElement.getKey().getColumnAttribute() != null ) {
|
||||
if ( joinElement.getKey().getColumn().size() > 0 ) {
|
||||
throw bindingContext.makeMappingException( "<join/> defined both column attribute and nested <column/>" );
|
||||
throw makeMappingException( "<join/> defined both column attribute and nested <column/>" );
|
||||
}
|
||||
joinColumns.add(
|
||||
new PrimaryKeyJoinColumnSource() {
|
||||
|
@ -108,4 +110,10 @@ public class SecondaryTableSourceImpl implements SecondaryTableSource {
|
|||
public List<PrimaryKeyJoinColumnSource> getJoinColumns() {
|
||||
return joinColumns;
|
||||
}
|
||||
|
||||
public String getLogicalTableNameForContainedColumns() {
|
||||
return TableSource.class.isInstance( joinTable )
|
||||
? ( (TableSource) joinTable ).getExplicitTableName()
|
||||
: ( (InLineViewSource) joinTable ).getLogicalName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.internal.source.hbm;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.internal.jaxb.mapping.hbm.EntityElement;
|
||||
import org.hibernate.internal.jaxb.mapping.hbm.JaxbSubclassElement;
|
||||
import org.hibernate.internal.jaxb.mapping.hbm.TableInformationSource;
|
||||
|
@ -44,10 +46,7 @@ public class SubclassEntitySourceImpl extends AbstractEntitySourceImpl implement
|
|||
super( sourceMappingDocument, entityElement );
|
||||
this.container = container;
|
||||
this.primaryTable = TableInformationSource.class.isInstance( entityElement )
|
||||
? Helper.createTableSource(
|
||||
(TableInformationSource) entityElement,
|
||||
sourceMappingDocument.getMappingLocalBindingContext().determineEntityName( entityElement )
|
||||
)
|
||||
? Helper.createTableSource( (TableInformationSource) entityElement, this )
|
||||
: null;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public class EntityBinding implements AttributeBindingContainer {
|
|||
private Entity entity;
|
||||
private TableSpecification primaryTable;
|
||||
private String primaryTableName;
|
||||
private Map<String, TableSpecification> secondaryTables = new HashMap<String, TableSpecification>();
|
||||
private Map<String, SecondaryTable> secondaryTables = new HashMap<String, SecondaryTable>();
|
||||
|
||||
private Value<Class<?>> proxyInterfaceType;
|
||||
|
||||
|
@ -234,17 +234,17 @@ public class EntityBinding implements AttributeBindingContainer {
|
|||
if ( tableName == null || tableName.equals( getPrimaryTableName() ) ) {
|
||||
return primaryTable;
|
||||
}
|
||||
TableSpecification tableSpec = secondaryTables.get( tableName );
|
||||
if ( tableSpec == null ) {
|
||||
throw new AssertionFailure(
|
||||
String.format(
|
||||
"Unable to find table %s amongst tables %s",
|
||||
tableName,
|
||||
secondaryTables.keySet()
|
||||
)
|
||||
);
|
||||
}
|
||||
return tableSpec;
|
||||
SecondaryTable secondaryTable = secondaryTables.get( tableName );
|
||||
if ( secondaryTable == null ) {
|
||||
throw new AssertionFailure(
|
||||
String.format(
|
||||
"Unable to find table %s amongst tables %s",
|
||||
tableName,
|
||||
secondaryTables.keySet()
|
||||
)
|
||||
);
|
||||
}
|
||||
return secondaryTable.getSecondaryTableReference();
|
||||
}
|
||||
public String getPrimaryTableName() {
|
||||
return primaryTableName;
|
||||
|
@ -254,8 +254,8 @@ public class EntityBinding implements AttributeBindingContainer {
|
|||
this.primaryTableName = primaryTableName;
|
||||
}
|
||||
|
||||
public void addSecondaryTable(String tableName, TableSpecification table) {
|
||||
secondaryTables.put( tableName, table );
|
||||
public void addSecondaryTable(SecondaryTable secondaryTable) {
|
||||
secondaryTables.put( secondaryTable.getSecondaryTableReference().getLogicalName().getName(), secondaryTable );
|
||||
}
|
||||
|
||||
public boolean isVersioned() {
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, 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.spi.binding;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ForeignKey;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SecondaryTable {
|
||||
private final TableSpecification secondaryTableReference;
|
||||
private final ForeignKey foreignKeyReference;
|
||||
|
||||
public SecondaryTable(TableSpecification secondaryTableReference, ForeignKey foreignKeyReference) {
|
||||
this.secondaryTableReference = secondaryTableReference;
|
||||
this.foreignKeyReference = foreignKeyReference;
|
||||
}
|
||||
|
||||
public TableSpecification getSecondaryTableReference() {
|
||||
return secondaryTableReference;
|
||||
}
|
||||
|
||||
public ForeignKey getForeignKeyReference() {
|
||||
return foreignKeyReference;
|
||||
}
|
||||
}
|
|
@ -64,10 +64,7 @@ public abstract class AbstractTableSpecification implements TableSpecification {
|
|||
if ( valueMap.containsKey( name ) ) {
|
||||
return (Column) valueMap.get( name );
|
||||
}
|
||||
final Column column = new Column( this, valueList.size(), name );
|
||||
valueMap.put( name, column );
|
||||
valueList.add( column );
|
||||
return column;
|
||||
return createColumn( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,6 +75,14 @@ public abstract class AbstractTableSpecification implements TableSpecification {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Column createColumn(String name) {
|
||||
final Column column = new Column( this, valueList.size(), name );
|
||||
valueMap.put( name, column );
|
||||
valueList.add( column );
|
||||
return column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DerivedValue locateOrCreateDerivedValue(String fragment) {
|
||||
if ( valueMap.containsKey( fragment ) ) {
|
||||
|
|
|
@ -77,6 +77,8 @@ public interface TableSpecification extends ValueContainer, Loggable {
|
|||
*/
|
||||
public Column locateColumn(String name);
|
||||
|
||||
public Column createColumn(String name);
|
||||
|
||||
/**
|
||||
* Factory method for creating a {@link DerivedValue} associated with this container.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue