HHH-6092 : Domain and relational state for SimpleAttributeBinding
This commit is contained in:
parent
014702fa23
commit
412fa9406f
|
@ -102,8 +102,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
|
||||||
return attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void setAttribute(Attribute attribute) {
|
||||||
public void setAttribute(Attribute attribute) {
|
|
||||||
this.attribute = attribute;
|
this.attribute = attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +111,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void setValue(Value value) {
|
||||||
public void setValue(Value value) {
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,8 +213,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
|
||||||
return isLazy;
|
return isLazy;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract boolean isLazyDefault(MappingDefaults defaults);
|
|
||||||
|
|
||||||
protected void setLazy(boolean isLazy) {
|
protected void setLazy(boolean isLazy) {
|
||||||
this.isLazy = isLazy;
|
this.isLazy = isLazy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,13 +52,6 @@ public interface AttributeBinding {
|
||||||
*/
|
*/
|
||||||
public Attribute getAttribute();
|
public Attribute getAttribute();
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the attribute being bound.
|
|
||||||
*
|
|
||||||
* @param attribute The attribute
|
|
||||||
*/
|
|
||||||
public void setAttribute(Attribute attribute);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the value bound
|
* Obtain the value bound
|
||||||
*
|
*
|
||||||
|
@ -66,13 +59,6 @@ public interface AttributeBinding {
|
||||||
*/
|
*/
|
||||||
public Value getValue();
|
public Value getValue();
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value being bound.
|
|
||||||
*
|
|
||||||
* @param value The value
|
|
||||||
*/
|
|
||||||
public void setValue(Value value);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the descriptor for the Hibernate Type for this binding.
|
* Obtain the descriptor for the Hibernate Type for this binding.
|
||||||
*
|
*
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.engine.Versioning;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.mapping.MetaAttribute;
|
import org.hibernate.mapping.MetaAttribute;
|
||||||
import org.hibernate.metamodel.domain.Entity;
|
import org.hibernate.metamodel.domain.Entity;
|
||||||
|
import org.hibernate.metamodel.relational.Column;
|
||||||
import org.hibernate.metamodel.relational.TableSpecification;
|
import org.hibernate.metamodel.relational.TableSpecification;
|
||||||
import org.hibernate.metamodel.source.hbm.HbmHelper;
|
import org.hibernate.metamodel.source.hbm.HbmHelper;
|
||||||
import org.hibernate.metamodel.source.util.DomHelper;
|
import org.hibernate.metamodel.source.util.DomHelper;
|
||||||
|
@ -84,7 +85,7 @@ public class EntityBinding {
|
||||||
|
|
||||||
private List<String> synchronizedTableNames;
|
private List<String> synchronizedTableNames;
|
||||||
|
|
||||||
// TODO: change to initialize from DomainState
|
// TODO: change to intialize from Doimain
|
||||||
public void fromHbmXml(MappingDefaults defaults, Element node, Entity entity) {
|
public void fromHbmXml(MappingDefaults defaults, Element node, Entity entity) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
metaAttributes = HbmHelper.extractMetas( node, true, defaults.getMappingMetas() );
|
metaAttributes = HbmHelper.extractMetas( node, true, defaults.getMappingMetas() );
|
||||||
|
@ -161,21 +162,33 @@ public class EntityBinding {
|
||||||
return entityIdentifier;
|
return entityIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityDiscriminator makeEntityDiscriminator() {
|
public void bindEntityIdentifier(SimpleAttributeBinding attributeBinding) {
|
||||||
entityDiscriminator = new EntityDiscriminator( this );
|
if ( ! Column.class.isInstance( attributeBinding.getValue() ) ) {
|
||||||
return entityDiscriminator;
|
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() {
|
public EntityDiscriminator getEntityDiscriminator() {
|
||||||
return entityDiscriminator;
|
return entityDiscriminator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleAttributeBinding getVersioningValueBinding() {
|
public void bindEntityDiscriminator(SimpleAttributeBinding attributeBinding) {
|
||||||
return versionBinding;
|
if ( ! Column.class.isInstance( attributeBinding.getValue() ) ) {
|
||||||
|
throw new MappingException(
|
||||||
|
"Identifier value must be a Column; instead it is: " + attributeBinding.getValue().getClass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
entityDiscriminator.setValueBinding( attributeBinding );
|
||||||
|
baseTable.getPrimaryKey().addColumn( Column.class.cast( attributeBinding.getValue() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVersioningValueBinding(SimpleAttributeBinding versionBinding) {
|
|
||||||
this.versionBinding = versionBinding;
|
public SimpleAttributeBinding getVersioningValueBinding() {
|
||||||
|
return versionBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<AttributeBinding> getAttributeBindings() {
|
public Iterable<AttributeBinding> getAttributeBindings() {
|
||||||
|
@ -186,8 +199,34 @@ public class EntityBinding {
|
||||||
return attributeBindingMap.get( name );
|
return attributeBindingMap.get( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SimpleAttributeBinding makeSimplePrimaryKeyAttributeBinding(String name) {
|
||||||
|
final SimpleAttributeBinding binding = makeSimpleAttributeBinding( name, true, true );
|
||||||
|
getEntityIdentifier().setValueBinding( binding );
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleAttributeBinding makeEntityDiscriminatorBinding(String name) {
|
||||||
|
if ( entityDiscriminator != null ) {
|
||||||
|
// TODO: LOG this!!!
|
||||||
|
}
|
||||||
|
entityDiscriminator = new EntityDiscriminator( this );
|
||||||
|
entityDiscriminator.setValueBinding( makeSimpleAttributeBinding( name, true, false ) );
|
||||||
|
return entityDiscriminator.getValueBinding();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleAttributeBinding makeVersionBinding(String name) {
|
||||||
|
versionBinding = makeSimpleAttributeBinding( name, true, false );
|
||||||
|
return versionBinding;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public SimpleAttributeBinding makeSimpleAttributeBinding(String name) {
|
public SimpleAttributeBinding makeSimpleAttributeBinding(String name) {
|
||||||
final SimpleAttributeBinding binding = new SimpleAttributeBinding( this );
|
return makeSimpleAttributeBinding( name, false, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
private SimpleAttributeBinding makeSimpleAttributeBinding(String name, boolean forceNonNullable, boolean forceUnique) {
|
||||||
|
final SimpleAttributeBinding binding = new SimpleAttributeBinding( this, forceNonNullable, forceUnique );
|
||||||
attributeBindingMap.put( name, binding );
|
attributeBindingMap.put( name, binding );
|
||||||
binding.setAttribute( entity.getAttribute( name ) );
|
binding.setAttribute( entity.getAttribute( name ) );
|
||||||
return binding;
|
return binding;
|
||||||
|
|
|
@ -25,6 +25,7 @@ package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
import org.hibernate.mapping.MetaAttribute;
|
import org.hibernate.mapping.MetaAttribute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,4 +38,5 @@ public interface MappingDefaults {
|
||||||
String getDefaultCascade();
|
String getDefaultCascade();
|
||||||
String getDefaultAccess();
|
String getDefaultAccess();
|
||||||
boolean isDefaultLazy();
|
boolean isDefaultLazy();
|
||||||
|
NamingStrategy getNamingStrategy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,19 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.binding;
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
import org.dom4j.Attribute;
|
import java.util.LinkedHashSet;
|
||||||
import org.dom4j.Element;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
import org.hibernate.mapping.PropertyGeneration;
|
import org.hibernate.mapping.PropertyGeneration;
|
||||||
import org.hibernate.metamodel.source.util.DomHelper;
|
import org.hibernate.metamodel.relational.Column;
|
||||||
|
import org.hibernate.metamodel.relational.DerivedValue;
|
||||||
|
import org.hibernate.metamodel.relational.SimpleValue;
|
||||||
|
import org.hibernate.metamodel.relational.Size;
|
||||||
|
import org.hibernate.metamodel.relational.TableSpecification;
|
||||||
|
import org.hibernate.metamodel.relational.Tuple;
|
||||||
|
import org.hibernate.metamodel.relational.Value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO : javadoc
|
* TODO : javadoc
|
||||||
|
@ -37,12 +44,38 @@ import org.hibernate.metamodel.source.util.DomHelper;
|
||||||
*/
|
*/
|
||||||
public class SimpleAttributeBinding extends SingularAttributeBinding {
|
public class SimpleAttributeBinding extends SingularAttributeBinding {
|
||||||
public static interface DomainState extends SingularAttributeBinding.DomainState {
|
public static interface DomainState extends SingularAttributeBinding.DomainState {
|
||||||
public abstract PropertyGeneration getPropertyGeneration();
|
public PropertyGeneration getPropertyGeneration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static interface SingleValueRelationalState {}
|
||||||
|
public static interface ColumnRelationalState extends SingleValueRelationalState {
|
||||||
|
NamingStrategy getNamingStrategy();
|
||||||
|
String getExplicitColumnName();
|
||||||
|
boolean isUnique();
|
||||||
|
Size getSize();
|
||||||
|
boolean isNullable();
|
||||||
|
String getCheckCondition();
|
||||||
|
String getDefault();
|
||||||
|
String getSqlType();
|
||||||
|
String getCustomWriteFragment();
|
||||||
|
String getCustomReadFragment();
|
||||||
|
String getComment();
|
||||||
|
Set<String> getUniqueKeys();
|
||||||
|
Set<String> getIndexes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface DerivedRelationalState extends SingleValueRelationalState {
|
||||||
|
String getFormula();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface TupleRelationalState {
|
||||||
|
LinkedHashSet<SingleValueRelationalState> getSingleValueRelationalStates();
|
||||||
|
}
|
||||||
|
|
||||||
private PropertyGeneration generation;
|
private PropertyGeneration generation;
|
||||||
|
|
||||||
SimpleAttributeBinding(EntityBinding entityBinding) {
|
SimpleAttributeBinding(EntityBinding entityBinding, boolean forceNonNullable, boolean forceUnique) {
|
||||||
super( entityBinding );
|
super( entityBinding, forceNonNullable, forceUnique );
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void initialize(DomainState state) {
|
public final void initialize(DomainState state) {
|
||||||
|
@ -50,8 +83,79 @@ public class SimpleAttributeBinding extends SingularAttributeBinding {
|
||||||
generation = state.getPropertyGeneration();
|
generation = state.getPropertyGeneration();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isLazyDefault(MappingDefaults defaults) {
|
public final void initializeColumnValue(ColumnRelationalState state) {
|
||||||
return false;
|
Column columnValue = createColumn( state );
|
||||||
|
setValue( columnValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Column createColumn(ColumnRelationalState state) {
|
||||||
|
final String explicitName = state.getExplicitColumnName();
|
||||||
|
final String logicalColumnName = state.getNamingStrategy().logicalColumnName( explicitName, getAttribute().getName() );
|
||||||
|
final TableSpecification table = getEntityBinding().getBaseTable();
|
||||||
|
final String columnName =
|
||||||
|
explicitName == null ?
|
||||||
|
state.getNamingStrategy().propertyToColumnName( getAttribute().getName() ) :
|
||||||
|
state.getNamingStrategy().columnName( explicitName );
|
||||||
|
// todo : find out the purpose of these logical bindings
|
||||||
|
// mappings.addColumnBinding( logicalColumnName, column, table );
|
||||||
|
Column columnValue = table.createColumn( columnName );
|
||||||
|
columnValue.getSize().initialize( state.getSize() );
|
||||||
|
columnValue.setNullable( ! forceNonNullable() && state.isNullable() );
|
||||||
|
columnValue.setUnique( ! forceUnique() && state.isUnique() );
|
||||||
|
columnValue.setCheckCondition( state.getCheckCondition() );
|
||||||
|
columnValue.setDefaultValue( state.getDefault() );
|
||||||
|
columnValue.setSqlType( state.getSqlType() );
|
||||||
|
columnValue.setWriteFragment( state.getCustomWriteFragment() );
|
||||||
|
columnValue.setReadFragment( state.getCustomReadFragment() );
|
||||||
|
columnValue.setComment( state.getComment() );
|
||||||
|
for ( String uniqueKey : state.getUniqueKeys() ) {
|
||||||
|
table.getOrCreateUniqueKey( uniqueKey ).addColumn( columnValue );
|
||||||
|
}
|
||||||
|
for ( String index : state.getIndexes() ) {
|
||||||
|
table.getOrCreateIndex( index ).addColumn( columnValue );
|
||||||
|
}
|
||||||
|
return columnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUnique(ColumnRelationalState state) {
|
||||||
|
return isPrimaryKey() || state.isUnique();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final <T extends DerivedRelationalState> void initializeDerivedValue(T state) {
|
||||||
|
setValue( createDerivedValue( state ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private DerivedValue createDerivedValue(DerivedRelationalState state) {
|
||||||
|
return getEntityBinding().getBaseTable().createDerivedValue( state.getFormula() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void initializeTupleValue(TupleRelationalState state) {
|
||||||
|
if ( state.getSingleValueRelationalStates().size() == 0 ) {
|
||||||
|
throw new MappingException( "Tuple state does not contain any values." );
|
||||||
|
}
|
||||||
|
if ( state.getSingleValueRelationalStates().size() == 1 ) {
|
||||||
|
setValue( createSingleValue( state.getSingleValueRelationalStates().iterator().next() ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Tuple tuple = getEntityBinding().getBaseTable().createTuple( "[" + getAttribute().getName() + "]" );
|
||||||
|
for ( SingleValueRelationalState singleValueState : state.getSingleValueRelationalStates() ) {
|
||||||
|
tuple.addValue( createSingleValue( singleValueState ) );
|
||||||
|
}
|
||||||
|
setValue( tuple );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SimpleValue createSingleValue(SingleValueRelationalState state) {
|
||||||
|
if ( state instanceof ColumnRelationalState ) {
|
||||||
|
return createColumn( ColumnRelationalState.class.cast( state ) );
|
||||||
|
}
|
||||||
|
else if ( state instanceof DerivedRelationalState ) {
|
||||||
|
return createDerivedValue( DerivedRelationalState.class.cast( state ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new MappingException( "unknown relational state:" + state.getClass().getName() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,6 +163,10 @@ public class SimpleAttributeBinding extends SingularAttributeBinding {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isPrimaryKey() {
|
||||||
|
return this == getEntityBinding().getEntityIdentifier().getValueBinding();
|
||||||
|
}
|
||||||
|
|
||||||
public PropertyGeneration getGeneration() {
|
public PropertyGeneration getGeneration() {
|
||||||
return generation;
|
return generation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,17 @@ public abstract class SingularAttributeBinding extends AbstractAttributeBinding
|
||||||
String getUnsavedValue();
|
String getUnsavedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final boolean forceNonNullable;
|
||||||
|
private final boolean forceUnique;
|
||||||
private boolean insertable;
|
private boolean insertable;
|
||||||
private boolean updateable;
|
private boolean updateable;
|
||||||
private boolean keyCasadeDeleteEnabled;
|
private boolean keyCasadeDeleteEnabled;
|
||||||
private String unsavedValue;
|
private String unsavedValue;
|
||||||
|
|
||||||
SingularAttributeBinding(EntityBinding entityBinding) {
|
SingularAttributeBinding(EntityBinding entityBinding, boolean forceNonNullable, boolean forceUnique) {
|
||||||
super( entityBinding );
|
super( entityBinding );
|
||||||
|
this.forceNonNullable = forceNonNullable;
|
||||||
|
this.forceUnique = forceUnique;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void initialize(DomainState state) {
|
public final void initialize(DomainState state) {
|
||||||
|
@ -91,4 +95,12 @@ public abstract class SingularAttributeBinding extends AbstractAttributeBinding
|
||||||
public void setUnsavedValue(String unsaveValue) {
|
public void setUnsavedValue(String unsaveValue) {
|
||||||
this.unsavedValue = unsaveValue;
|
this.unsavedValue = unsaveValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean forceNonNullable() {
|
||||||
|
return forceNonNullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean forceUnique() {
|
||||||
|
return forceUnique;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,12 @@ public class Size implements Serializable {
|
||||||
return lobMultiplier;
|
return lobMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initialize(Size size) {
|
||||||
|
this.precision = size.precision;
|
||||||
|
this.scale = size.scale;
|
||||||
|
this.length = size.length;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPrecision(int precision) {
|
public void setPrecision(int precision) {
|
||||||
this.precision = precision;
|
this.precision = precision;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.hbm;
|
package org.hibernate.metamodel.source.hbm;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import org.dom4j.Attribute;
|
import org.dom4j.Attribute;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
|
@ -46,18 +42,14 @@ import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||||
import org.hibernate.metamodel.domain.Entity;
|
import org.hibernate.metamodel.domain.Entity;
|
||||||
import org.hibernate.metamodel.domain.Hierarchical;
|
import org.hibernate.metamodel.domain.Hierarchical;
|
||||||
import org.hibernate.metamodel.domain.PluralAttributeNature;
|
import org.hibernate.metamodel.domain.PluralAttributeNature;
|
||||||
import org.hibernate.metamodel.relational.Column;
|
|
||||||
import org.hibernate.metamodel.relational.Index;
|
|
||||||
import org.hibernate.metamodel.relational.Schema;
|
import org.hibernate.metamodel.relational.Schema;
|
||||||
import org.hibernate.metamodel.relational.SimpleValue;
|
|
||||||
import org.hibernate.metamodel.relational.Table;
|
import org.hibernate.metamodel.relational.Table;
|
||||||
import org.hibernate.metamodel.relational.TableSpecification;
|
import org.hibernate.metamodel.relational.TableSpecification;
|
||||||
import org.hibernate.metamodel.relational.Tuple;
|
|
||||||
import org.hibernate.metamodel.relational.UniqueKey;
|
import org.hibernate.metamodel.relational.UniqueKey;
|
||||||
import org.hibernate.metamodel.relational.Value;
|
|
||||||
import org.hibernate.metamodel.source.Metadata;
|
import org.hibernate.metamodel.source.Metadata;
|
||||||
import org.hibernate.metamodel.source.hbm.state.domain.HbmPluralAttributeDomainState;
|
import org.hibernate.metamodel.source.hbm.state.domain.HbmPluralAttributeDomainState;
|
||||||
import org.hibernate.metamodel.source.hbm.state.domain.HbmSimpleAttributeDomainState;
|
import org.hibernate.metamodel.source.hbm.state.domain.HbmSimpleAttributeDomainState;
|
||||||
|
import org.hibernate.metamodel.source.hbm.state.relational.HbmSimpleValueRelationalStateContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO : javadoc
|
* TODO : javadoc
|
||||||
|
@ -416,7 +408,10 @@ abstract class AbstractEntityBinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bindSimpleAttribute(Element propertyElement, SimpleAttributeBinding attributeBinding, EntityBinding entityBinding, String attributeName) {
|
protected void bindSimpleAttribute(Element propertyElement,
|
||||||
|
SimpleAttributeBinding attributeBinding,
|
||||||
|
EntityBinding entityBinding,
|
||||||
|
String attributeName) {
|
||||||
if ( attributeBinding.getAttribute() == null ) {
|
if ( attributeBinding.getAttribute() == null ) {
|
||||||
attributeBinding.initialize(
|
attributeBinding.initialize(
|
||||||
new HbmSimpleAttributeDomainState(
|
new HbmSimpleAttributeDomainState(
|
||||||
|
@ -429,8 +424,14 @@ abstract class AbstractEntityBinder {
|
||||||
|
|
||||||
if ( attributeBinding.getValue() == null ) {
|
if ( attributeBinding.getValue() == null ) {
|
||||||
// relational model has not been bound yet
|
// relational model has not been bound yet
|
||||||
Value idValue = processValues( propertyElement, entityBinding.getBaseTable(), attributeName );
|
// boolean (true here) indicates that by default column names should be guessed
|
||||||
attributeBinding.setValue( idValue );
|
attributeBinding.initializeTupleValue(
|
||||||
|
new HbmSimpleValueRelationalStateContainer(
|
||||||
|
getHibernateMappingBinder(),
|
||||||
|
propertyElement,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,57 +496,10 @@ abstract class AbstractEntityBinder {
|
||||||
// return prop;
|
// return prop;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
protected Value processValues(Element identifierElement, TableSpecification baseTable, String propertyPath) {
|
|
||||||
|
// protected HbmRelationalState processValues(Element identifierElement, TableSpecification baseTable, String propertyPath, boolean isSimplePrimaryKey) {
|
||||||
// first boolean (false here) indicates that by default columns are nullable
|
// first boolean (false here) indicates that by default columns are nullable
|
||||||
// second boolean (true here) indicates that by default column names should be guessed
|
// second boolean (true here) indicates that by default column names should be guessed
|
||||||
return processValues( identifierElement, baseTable, false, true, propertyPath );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Value processValues(
|
|
||||||
Element propertyElement,
|
|
||||||
TableSpecification table,
|
|
||||||
boolean isNullableByDefault,
|
|
||||||
boolean autoColumnCreation,
|
|
||||||
String propertyPath) {
|
|
||||||
final UniqueKeyBinder propertyUniqueKeyBinder = new UniqueKeyBinder( propertyElement.attribute( "unique-key" ), table );
|
|
||||||
final IndexBinder propertyIndexBinder = new IndexBinder( propertyElement.attribute( "index" ), table );
|
|
||||||
|
|
||||||
final Attribute columnAttribute = propertyElement.attribute( "column" );
|
|
||||||
|
|
||||||
if ( columnAttribute == null ) {
|
|
||||||
SimpleValue value = null;
|
|
||||||
Tuple tuple = null;
|
|
||||||
final Iterator valueElements = propertyElement.elementIterator();
|
|
||||||
while ( valueElements.hasNext() ) {
|
|
||||||
if ( value != null ) {
|
|
||||||
if ( tuple == null ) {
|
|
||||||
tuple = table.createTuple( "[" + propertyPath + "]" );
|
|
||||||
}
|
|
||||||
tuple.addValue( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
final Element valueElement = (Element) valueElements.next();
|
|
||||||
if ( "column".equals( valueElement.getName() ) ) {
|
|
||||||
final Element columnElement = valueElement;
|
|
||||||
final String explicitName = columnElement.attributeValue( "name" );
|
|
||||||
final String logicalColumnName = getNamingStrategy().logicalColumnName( explicitName, propertyPath );
|
|
||||||
final String columnName = getNamingStrategy().columnName( explicitName );
|
|
||||||
// todo : find out the purpose of these logical bindings
|
|
||||||
// mappings.addColumnBinding( logicalColumnName, column, table );
|
|
||||||
Column column = table.createColumn( columnName );
|
|
||||||
value = column;
|
|
||||||
basicColumnBinding( columnElement, column, isNullableByDefault );
|
|
||||||
|
|
||||||
propertyUniqueKeyBinder.bindColumn( column );
|
|
||||||
propertyIndexBinder.bindColumn( column );
|
|
||||||
new UniqueKeyBinder( columnElement.attribute( "unique-key" ), table ).bindColumn( column );
|
|
||||||
new IndexBinder( columnElement.attribute( "index" ), table ).bindColumn( column );
|
|
||||||
}
|
|
||||||
else if ( "formula".equals( valueElement.getName() ) ) {
|
|
||||||
value = table.createDerivedValue( valueElement.getTextTrim() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo : logical 1-1 handling
|
// todo : logical 1-1 handling
|
||||||
// final Attribute uniqueAttribute = node.attribute( "unique" );
|
// final Attribute uniqueAttribute = node.attribute( "unique" );
|
||||||
// if ( uniqueAttribute != null
|
// if ( uniqueAttribute != null
|
||||||
|
@ -553,130 +507,8 @@ abstract class AbstractEntityBinder {
|
||||||
// && ManyToOne.class.isInstance( simpleValue ) ) {
|
// && ManyToOne.class.isInstance( simpleValue ) ) {
|
||||||
// ( (ManyToOne) simpleValue ).markAsLogicalOneToOne();
|
// ( (ManyToOne) simpleValue ).markAsLogicalOneToOne();
|
||||||
// }
|
// }
|
||||||
|
//return processValues( identifierElement, baseTable, false, true, propertyPath, isSimplePrimaryKey );
|
||||||
|
|
||||||
if ( tuple != null ) {
|
|
||||||
return tuple;
|
|
||||||
}
|
|
||||||
else if ( value != null ) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
else if ( autoColumnCreation ) {
|
|
||||||
final String columnName = getNamingStrategy().propertyToColumnName( propertyPath );
|
|
||||||
final String logicalColumnName = getNamingStrategy().logicalColumnName( null, propertyPath );
|
|
||||||
// todo : find out the purpose of these logical bindings
|
|
||||||
// mappings.addColumnBinding( logicalColumnName, column, table );
|
|
||||||
Column column = table.createColumn( columnName );
|
|
||||||
basicColumnBinding( propertyElement, column, isNullableByDefault );
|
|
||||||
propertyUniqueKeyBinder.bindColumn( column );
|
|
||||||
propertyIndexBinder.bindColumn( column );
|
|
||||||
return column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( propertyElement.elementIterator( "column" ).hasNext() ) {
|
|
||||||
throw new MappingException( "column attribute may not be used together with <column> subelement" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( propertyElement.elementIterator( "formula" ).hasNext() ) {
|
}
|
||||||
throw new MappingException( "column attribute may not be used together with <formula> subelement" );
|
|
||||||
}
|
|
||||||
|
|
||||||
final String explicitName = columnAttribute.getValue();
|
|
||||||
final String logicalColumnName = getNamingStrategy().logicalColumnName( explicitName, propertyPath );
|
|
||||||
final String columnName = getNamingStrategy().columnName( explicitName );
|
|
||||||
// todo : find out the purpose of these logical bindings
|
|
||||||
// mappings.addColumnBinding( logicalColumnName, column, table );
|
|
||||||
Column column = table.createColumn( columnName );
|
|
||||||
basicColumnBinding( propertyElement, column, isNullableByDefault );
|
|
||||||
propertyUniqueKeyBinder.bindColumn( column );
|
|
||||||
propertyIndexBinder.bindColumn( column );
|
|
||||||
return column;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class UniqueKeyBinder {
|
|
||||||
private final List<UniqueKey> uniqueKeys;
|
|
||||||
|
|
||||||
UniqueKeyBinder(Attribute uniqueKeyAttribute, TableSpecification table) {
|
|
||||||
if ( uniqueKeyAttribute == null ) {
|
|
||||||
uniqueKeys = Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uniqueKeys = new ArrayList<UniqueKey>();
|
|
||||||
StringTokenizer uniqueKeyNames = new StringTokenizer( uniqueKeyAttribute.getValue(), ", " );
|
|
||||||
while ( uniqueKeyNames.hasMoreTokens() ) {
|
|
||||||
uniqueKeys.add( table.getOrCreateUniqueKey( uniqueKeyNames.nextToken() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bindColumn(Column column) {
|
|
||||||
for ( UniqueKey uniqueKey : uniqueKeys ) {
|
|
||||||
uniqueKey.addColumn( column );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class IndexBinder {
|
|
||||||
private final List<Index> indexes;
|
|
||||||
|
|
||||||
IndexBinder(Attribute indexAttribute, TableSpecification table) {
|
|
||||||
if ( indexAttribute == null ) {
|
|
||||||
indexes = Collections.emptyList();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
indexes = new ArrayList<Index>();
|
|
||||||
StringTokenizer indexNames = new StringTokenizer( indexAttribute.getValue(), ", " );
|
|
||||||
while ( indexNames.hasMoreTokens() ) {
|
|
||||||
indexes.add( table.getOrCreateIndex( indexNames.nextToken() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bindColumn(Column column) {
|
|
||||||
for ( Index index : indexes ) {
|
|
||||||
index.addColumn( column );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void basicColumnBinding(Element node, Column column, boolean isNullable) throws MappingException {
|
|
||||||
Attribute lengthNode = node.attribute( "length" );
|
|
||||||
if ( lengthNode != null ) {
|
|
||||||
column.getSize().setLength( Integer.parseInt( lengthNode.getValue() ) );
|
|
||||||
}
|
|
||||||
Attribute scalNode = node.attribute( "scale" );
|
|
||||||
if ( scalNode != null ) {
|
|
||||||
column.getSize().setScale( Integer.parseInt( scalNode.getValue() ) );
|
|
||||||
}
|
|
||||||
Attribute precNode = node.attribute( "precision" );
|
|
||||||
if ( precNode != null ) {
|
|
||||||
column.getSize().setPrecision( Integer.parseInt( precNode.getValue() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
Attribute nullNode = node.attribute( "not-null" );
|
|
||||||
column.setNullable( nullNode == null ? isNullable : nullNode.getValue().equals( "false" ) );
|
|
||||||
|
|
||||||
Attribute unqNode = node.attribute( "unique" );
|
|
||||||
if ( unqNode != null ) {
|
|
||||||
column.setUnique( unqNode.getValue().equals( "true" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
column.setCheckCondition( node.attributeValue( "check" ) );
|
|
||||||
column.setDefaultValue( node.attributeValue( "default" ) );
|
|
||||||
|
|
||||||
Attribute typeNode = node.attribute( "sql-type" );
|
|
||||||
if ( typeNode != null ) column.setSqlType( typeNode.getValue() );
|
|
||||||
|
|
||||||
String customWrite = node.attributeValue( "write" );
|
|
||||||
if(customWrite != null && !customWrite.matches("[^?]*\\?[^?]*")) {
|
|
||||||
throw new MappingException("write expression must contain exactly one value placeholder ('?') character");
|
|
||||||
}
|
|
||||||
column.setWriteFragment( customWrite );
|
|
||||||
column.setReadFragment( node.attributeValue( "read" ) );
|
|
||||||
|
|
||||||
Element comment = node.element("comment");
|
|
||||||
if ( comment != null ) {
|
|
||||||
column.setComment( comment.getTextTrim() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -30,6 +30,7 @@ import org.dom4j.Attribute;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.xml.XmlDocument;
|
import org.hibernate.internal.util.xml.XmlDocument;
|
||||||
import org.hibernate.mapping.FetchProfile;
|
import org.hibernate.mapping.FetchProfile;
|
||||||
|
@ -100,6 +101,10 @@ class HibernateMappingBinder implements MappingDefaults {
|
||||||
return defaultLazy;
|
return defaultLazy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NamingStrategy getNamingStrategy() {
|
||||||
|
return hibernateXmlBinder.getMetadata().getNamingStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
String getPackageName() {
|
String getPackageName() {
|
||||||
return packageName;
|
return packageName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,10 @@ import org.hibernate.mapping.RootClass;
|
||||||
import org.hibernate.metamodel.binding.Caching;
|
import org.hibernate.metamodel.binding.Caching;
|
||||||
import org.hibernate.metamodel.binding.EntityBinding;
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||||
import org.hibernate.metamodel.domain.Entity;
|
|
||||||
import org.hibernate.metamodel.relational.Column;
|
import org.hibernate.metamodel.relational.Column;
|
||||||
import org.hibernate.metamodel.relational.Identifier;
|
import org.hibernate.metamodel.relational.Identifier;
|
||||||
import org.hibernate.metamodel.relational.InLineView;
|
import org.hibernate.metamodel.relational.InLineView;
|
||||||
import org.hibernate.metamodel.relational.Schema;
|
import org.hibernate.metamodel.relational.Schema;
|
||||||
import org.hibernate.metamodel.relational.Tuple;
|
|
||||||
import org.hibernate.metamodel.relational.Value;
|
import org.hibernate.metamodel.relational.Value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,27 +145,16 @@ class RootEntityBinder extends AbstractEntityBinder {
|
||||||
final String attributeName = explicitName == null ? RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME : explicitName;
|
final String attributeName = explicitName == null ? RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME : explicitName;
|
||||||
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
|
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
|
||||||
|
|
||||||
SimpleAttributeBinding idBinding = entityBinding.makeSimpleAttributeBinding( attributeName );
|
SimpleAttributeBinding idBinding = entityBinding.makeSimplePrimaryKeyAttributeBinding( attributeName );
|
||||||
|
|
||||||
bindSimpleAttribute( identifierElement, idBinding, entityBinding, attributeName );
|
bindSimpleAttribute( identifierElement, idBinding, entityBinding, attributeName );
|
||||||
|
|
||||||
// Handle the relational portion of the binding...
|
if ( ! Column.class.isInstance( idBinding.getValue() ) ) {
|
||||||
Value idValue = processValues( identifierElement, entityBinding.getBaseTable(), attributeName );
|
|
||||||
idBinding.setValue( idValue );
|
|
||||||
|
|
||||||
// ear-mark this value binding as the identifier...
|
|
||||||
entityBinding.getEntityIdentifier().setValueBinding( idBinding );
|
|
||||||
|
|
||||||
if ( idValue instanceof Tuple ) {
|
|
||||||
// this should never ever happen..
|
// this should never ever happen..
|
||||||
throw new MappingException( "Unanticipated situation" );
|
throw new MappingException( "Unanticipated situation" );
|
||||||
}
|
}
|
||||||
|
|
||||||
entityBinding.getBaseTable().getPrimaryKey().addColumn( (Column) idValue );
|
entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( idBinding.getValue() ) );
|
||||||
|
|
||||||
// SimpleValue id = new SimpleValue( mappings, entity.getTable() );
|
|
||||||
// entity.setIdentifier( id );
|
|
||||||
|
|
||||||
// if ( propertyName == null || entity.getPojoRepresentation() == null ) {
|
// if ( propertyName == null || entity.getPojoRepresentation() == null ) {
|
||||||
// bindSimpleValue( idNode, id, false, RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME, mappings );
|
// bindSimpleValue( idNode, id, false, RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME, mappings );
|
||||||
// if ( !id.isTypeSpecified() ) {
|
// if ( !id.isTypeSpecified() ) {
|
||||||
|
@ -258,21 +245,14 @@ class RootEntityBinder extends AbstractEntityBinder {
|
||||||
final String attributeName = explicitName == null ? RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME : explicitName;
|
final String attributeName = explicitName == null ? RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME : explicitName;
|
||||||
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
|
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
|
||||||
|
|
||||||
SimpleAttributeBinding discriminatorBinding = entityBinding.makeSimpleAttributeBinding( attributeName );
|
SimpleAttributeBinding discriminatorBinding = entityBinding.makeEntityDiscriminatorBinding( attributeName );
|
||||||
|
|
||||||
|
// Handle the relational portion of the binding...
|
||||||
bindSimpleAttribute( discriminatorElement, discriminatorBinding, entityBinding, attributeName );
|
bindSimpleAttribute( discriminatorElement, discriminatorBinding, entityBinding, attributeName );
|
||||||
if ( discriminatorBinding.getHibernateTypeDescriptor().getTypeName() == null ) {
|
if ( discriminatorBinding.getHibernateTypeDescriptor().getTypeName() == null ) {
|
||||||
discriminatorBinding.getHibernateTypeDescriptor().setTypeName( "string" );
|
discriminatorBinding.getHibernateTypeDescriptor().setTypeName( "string" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the relational portion of the binding...
|
|
||||||
Value discriminatorValue = processValues( discriminatorElement, entityBinding.getBaseTable(), attributeName );
|
|
||||||
discriminatorBinding.setValue( discriminatorValue );
|
|
||||||
|
|
||||||
// ear-mark this value binding as the discriminator...
|
|
||||||
entityBinding.makeEntityDiscriminator();
|
|
||||||
entityBinding.getEntityDiscriminator().setValueBinding( discriminatorBinding );
|
|
||||||
|
|
||||||
if ( "true".equals( discriminatorElement.attributeValue( "force" ) ) ) {
|
if ( "true".equals( discriminatorElement.attributeValue( "force" ) ) ) {
|
||||||
entityBinding.getEntityDiscriminator().setForced( true );
|
entityBinding.getEntityDiscriminator().setForced( true );
|
||||||
}
|
}
|
||||||
|
@ -297,7 +277,7 @@ class RootEntityBinder extends AbstractEntityBinder {
|
||||||
throw new MappingException( "Mising property name for version/timestamp mapping [" + entityBinding.getEntity().getName() + "]" );
|
throw new MappingException( "Mising property name for version/timestamp mapping [" + entityBinding.getEntity().getName() + "]" );
|
||||||
}
|
}
|
||||||
entityBinding.getEntity().getOrCreateSingularAttribute( explicitName );
|
entityBinding.getEntity().getOrCreateSingularAttribute( explicitName );
|
||||||
SimpleAttributeBinding versionBinding = entityBinding.makeSimpleAttributeBinding( explicitName );
|
SimpleAttributeBinding versionBinding = entityBinding.makeVersionBinding( explicitName );
|
||||||
bindSimpleAttribute( versioningElement, versionBinding, entityBinding, explicitName );
|
bindSimpleAttribute( versioningElement, versionBinding, entityBinding, explicitName );
|
||||||
|
|
||||||
if ( versionBinding.getHibernateTypeDescriptor().getTypeName() == null ) {
|
if ( versionBinding.getHibernateTypeDescriptor().getTypeName() == null ) {
|
||||||
|
@ -315,18 +295,12 @@ class RootEntityBinder extends AbstractEntityBinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the relational portion of the binding...
|
|
||||||
Value discriminatorValue = processValues( versioningElement, entityBinding.getBaseTable(), explicitName );
|
|
||||||
versionBinding.setValue( discriminatorValue );
|
|
||||||
|
|
||||||
// for version properties marked as being generated, make sure they are "always"
|
// for version properties marked as being generated, make sure they are "always"
|
||||||
// generated; aka, "insert" is invalid; this is dis-allowed by the DTD,
|
// generated; aka, "insert" is invalid; this is dis-allowed by the DTD,
|
||||||
// but just to make sure...
|
// but just to make sure...
|
||||||
if ( versionBinding.getGeneration() == PropertyGeneration.INSERT ) {
|
if ( versionBinding.getGeneration() == PropertyGeneration.INSERT ) {
|
||||||
throw new MappingException( "'generated' attribute cannot be 'insert' for versioning property" );
|
throw new MappingException( "'generated' attribute cannot be 'insert' for versioning property" );
|
||||||
}
|
}
|
||||||
|
|
||||||
entityBinding.setVersioningValueBinding( versionBinding );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindCaching(Element entityElement, EntityBinding entityBinding) {
|
private void bindCaching(Element entityElement, EntityBinding entityBinding) {
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.source.hbm.state.relational;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
|
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||||
|
import org.hibernate.metamodel.relational.Size;
|
||||||
|
import org.hibernate.metamodel.source.util.DomHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class HbmColumnRelationalState extends HbmRelationalState implements SimpleAttributeBinding.ColumnRelationalState {
|
||||||
|
private final HbmSimpleValueRelationalStateContainer container;
|
||||||
|
|
||||||
|
/* package-protected */
|
||||||
|
HbmColumnRelationalState(Element columnElement,
|
||||||
|
HbmSimpleValueRelationalStateContainer container) {
|
||||||
|
super( columnElement );
|
||||||
|
this.container = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamingStrategy getNamingStrategy() {
|
||||||
|
return container.getNamingStrategy();
|
||||||
|
}
|
||||||
|
public String getExplicitColumnName() {
|
||||||
|
return getElement().attributeValue( "name" );
|
||||||
|
}
|
||||||
|
public Size getSize() {
|
||||||
|
// TODO: should this set defaults if length, scale, precision is not specified?
|
||||||
|
Size size = new Size();
|
||||||
|
org.dom4j.Attribute lengthNode = getElement().attribute( "length" );
|
||||||
|
if ( lengthNode != null ) {
|
||||||
|
size.setLength( Integer.parseInt( lengthNode.getValue() ) );
|
||||||
|
}
|
||||||
|
org.dom4j.Attribute scaleNode = getElement().attribute( "scale" );
|
||||||
|
if ( scaleNode != null ) {
|
||||||
|
size.setScale( Integer.parseInt( scaleNode.getValue() ) );
|
||||||
|
}
|
||||||
|
org.dom4j.Attribute precisionNode = getElement().attribute( "precision" );
|
||||||
|
if ( precisionNode != null ) {
|
||||||
|
size.setPrecision( Integer.parseInt( precisionNode.getValue() ) );
|
||||||
|
}
|
||||||
|
// TODO: is there an attribute for lobMultiplier?
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
public boolean isNullable() {
|
||||||
|
return ! DomHelper.extractBooleanAttributeValue( getElement(), "not-null", false );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUnique() {
|
||||||
|
return ! DomHelper.extractBooleanAttributeValue( getElement(), "unique", false );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCheckCondition() {
|
||||||
|
return getElement().attributeValue( "check" );
|
||||||
|
}
|
||||||
|
public String getDefault() {
|
||||||
|
return getElement().attributeValue( "default" );
|
||||||
|
}
|
||||||
|
public String getSqlType() {
|
||||||
|
return getElement().attributeValue( "sql-type" );
|
||||||
|
}
|
||||||
|
public String getCustomWriteFragment() {
|
||||||
|
String customWrite = getElement().attributeValue( "write" );
|
||||||
|
if ( customWrite != null && ! customWrite.matches("[^?]*\\?[^?]*") ) {
|
||||||
|
throw new MappingException("write expression must contain exactly one value placeholder ('?') character");
|
||||||
|
}
|
||||||
|
return customWrite;
|
||||||
|
}
|
||||||
|
public String getCustomReadFragment() {
|
||||||
|
return getElement().attributeValue( "read" );
|
||||||
|
}
|
||||||
|
public String getComment() {
|
||||||
|
Element comment = getElement().element( "comment" );
|
||||||
|
return comment == null ?
|
||||||
|
null :
|
||||||
|
comment.getTextTrim();
|
||||||
|
}
|
||||||
|
public Set<String> getUniqueKeys() {
|
||||||
|
Set<String> uniqueKeys = DomHelper.extractUniqueAttributeValueTokens( getElement(), "unique-key", ", " );
|
||||||
|
uniqueKeys.addAll( container.getPropertyUniqueKeys() );
|
||||||
|
return uniqueKeys;
|
||||||
|
}
|
||||||
|
public Set<String> getIndexes() {
|
||||||
|
Set<String> indexes = DomHelper.extractUniqueAttributeValueTokens( getElement(), "index", ", " );
|
||||||
|
indexes.addAll( container.getPropertyIndexes() );
|
||||||
|
return indexes;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.source.hbm.state.relational;
|
||||||
|
|
||||||
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class HbmDerivedValueRelationalState extends HbmRelationalState implements SimpleAttributeBinding.DerivedRelationalState {
|
||||||
|
|
||||||
|
public HbmDerivedValueRelationalState(Element element, HbmSimpleValueRelationalStateContainer container) {
|
||||||
|
super( element );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormula() {
|
||||||
|
return getElement().getTextTrim();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.source.hbm.state.relational;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
|
import org.hibernate.metamodel.binding.MappingDefaults;
|
||||||
|
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||||
|
import org.hibernate.metamodel.relational.Size;
|
||||||
|
import org.hibernate.metamodel.relational.TableSpecification;
|
||||||
|
import org.hibernate.metamodel.source.util.DomHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class HbmRelationalState {
|
||||||
|
private final Element element;
|
||||||
|
|
||||||
|
public HbmRelationalState(Element element) {
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Element getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.source.hbm.state.relational;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.dom4j.Attribute;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
|
import org.hibernate.metamodel.binding.MappingDefaults;
|
||||||
|
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||||
|
import org.hibernate.metamodel.source.util.DomHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class HbmSimpleValueRelationalStateContainer extends HbmRelationalState implements SimpleAttributeBinding.TupleRelationalState {
|
||||||
|
private final MappingDefaults defaults;
|
||||||
|
private final Set<String> propertyUniqueKeys;
|
||||||
|
private final Set<String> propertyIndexes;
|
||||||
|
private final LinkedHashSet<SimpleAttributeBinding.SingleValueRelationalState> singleValueStates =
|
||||||
|
new LinkedHashSet<SimpleAttributeBinding.SingleValueRelationalState>();
|
||||||
|
|
||||||
|
public NamingStrategy getNamingStrategy() {
|
||||||
|
return defaults.getNamingStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HbmSimpleValueRelationalStateContainer(MappingDefaults defaults,
|
||||||
|
Element propertyElement,
|
||||||
|
boolean autoColumnCreation) {
|
||||||
|
super( propertyElement );
|
||||||
|
this.defaults = defaults;
|
||||||
|
this.propertyUniqueKeys = DomHelper.extractUniqueAttributeValueTokens( propertyElement, "unique-key", ", " );
|
||||||
|
this.propertyIndexes = DomHelper.extractUniqueAttributeValueTokens( propertyElement, "index", ", " );
|
||||||
|
final Attribute columnAttribute = getElement().attribute( "column" );
|
||||||
|
if ( columnAttribute == null ) {
|
||||||
|
final Iterator valueElements = getElement().elementIterator();
|
||||||
|
while ( valueElements.hasNext() ) {
|
||||||
|
final Element valueElement = (Element) valueElements.next();
|
||||||
|
if ( "column".equals( valueElement.getName() ) ) {
|
||||||
|
singleValueStates.add( new HbmColumnRelationalState( valueElement, this ) );
|
||||||
|
}
|
||||||
|
else if ( "formula".equals( valueElement.getName() ) ) {
|
||||||
|
singleValueStates.add( new HbmDerivedValueRelationalState( valueElement, this ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( propertyElement.elementIterator( "column" ).hasNext() ) {
|
||||||
|
throw new MappingException( "column attribute may not be used together with <column> subelement" );
|
||||||
|
}
|
||||||
|
if ( propertyElement.elementIterator( "formula" ).hasNext() ) {
|
||||||
|
throw new MappingException( "column attribute may not be used together with <formula> subelement" );
|
||||||
|
}
|
||||||
|
singleValueStates.add( new HbmColumnRelationalState( propertyElement, this ) );
|
||||||
|
}
|
||||||
|
// TODO: should it actually check for 0 columns???
|
||||||
|
if ( singleValueStates.isEmpty() && autoColumnCreation ) {
|
||||||
|
singleValueStates.add( new HbmColumnRelationalState( propertyElement, this ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedHashSet<SimpleAttributeBinding.SingleValueRelationalState> getSingleValueRelationalStates() {
|
||||||
|
return singleValueStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> getPropertyUniqueKeys() {
|
||||||
|
return propertyUniqueKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> getPropertyIndexes() {
|
||||||
|
return propertyIndexes;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,12 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.util;
|
package org.hibernate.metamodel.source.util;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.dom4j.Attribute;
|
import org.dom4j.Attribute;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
@ -74,5 +80,18 @@ public class DomHelper {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Set<String> extractUniqueAttributeValueTokens(Element element, String attributeName, String delimiters) {
|
||||||
|
String attributeValue = element.attributeValue( attributeName );
|
||||||
|
if ( attributeValue == null ) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
StringTokenizer tokenizer = new StringTokenizer( attributeValue, delimiters );
|
||||||
|
Set<String> tokens = new HashSet<String>();
|
||||||
|
while ( tokenizer.hasMoreTokens() ) {
|
||||||
|
tokens.add( tokenizer.nextToken() );
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue