HHH-7058 - Remove concept of org.hibernate.metamodel.spi.relational.Tuple

This commit is contained in:
Steve Ebersole 2012-02-13 12:23:14 -06:00
parent a2480c6f08
commit 0e746d2723
72 changed files with 1633 additions and 936 deletions

View File

@ -172,7 +172,7 @@ https://hibernate.onjira.com/browse/HHH/fixforversion/11550
* [HHH-6749] - FooBarTest.testLimit() fails on MS SQL Server due to dialect interpretation of max row
* [HHH-6750] - ASTParserLoadingTest.testAggregation() fails on MS SQL Server performing avg, presumably due to forcing result to match column type
* [HHH-6751] - Test failure due to inconsistent scale returned for BigDecimal properties
* [HHH-6755] - SQL Server/Sybase dialects don't have type mapping for binary datatype
* [HHH-6755] - SQL Server/Sybase dialects don't have type mapping for binary jdbcDataType
* [HHH-6756] - Test failures due to Oracle LONG limitatations
* [HHH-6757] - QueryCacheTest.testCaseInsensitiveComparison() fails for case-insensitive DBs
* [HHH-6758] - Test failure due to Oracle restrictions on Blob comparison and missing equals() and hashcode()

View File

@ -15,7 +15,7 @@
<note>
<title>Usage of the word <wordasword>type</wordasword></title>
<para>
A Hibernate <classname>type</classname> is neither a Java type nor a SQL datatype. It provides information about
A Hibernate <classname>type</classname> is neither a Java type nor a SQL jdbcDataType. It provides information about
both of these.
</para>
<para>

View File

@ -552,7 +552,7 @@
<title>Set the <option>sql-type</option> attribure.</title>
<para>
Use the <option>sql-type</option> attribute to override the default mapping of a Hibernate type to SQL
datatype.
jdbcDataType.
</para>
<programlisting language="XML" role="XML"><xi:include href="extras/sql-type.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" /></programlisting>

View File

@ -176,7 +176,7 @@
<para>
The <literal>sql-type</literal> attribute allows the user to override the default
mapping of a Hibernate type to SQL datatype.
mapping of a Hibernate type to SQL jdbcDataType.
</para>
<programlisting role="XML"><![CDATA[<property name="balance" type="float">

View File

@ -39,7 +39,7 @@
<important>
<para>
A Hibernate type is neither a Java type nor a SQL datatype; it provides a information about both.
A Hibernate type is neither a Java type nor a SQL jdbcDataType; it provides a information about both.
</para>
<para>
When you encounter the term <emphasis>type</emphasis> in regards to Hibernate be aware that usage might

View File

@ -202,8 +202,8 @@
<para>
In some cases this automatic detection might not chose the default you expect or need, as seen with the
<varname>date</varname> property. Hibernate cannot know if the property, which is of type
<classname>java.util.Date</classname>, should map to a SQL <database class="datatype">DATE</database>,
<database class="datatype">TIME</database>, or <database class="datatype">TIMESTAMP</database> datatype.
<classname>java.util.Date</classname>, should map to a SQL <database class="jdbcDataType">DATE</database>,
<database class="jdbcDataType">TIME</database>, or <database class="jdbcDataType">TIMESTAMP</database> jdbcDataType.
Full date and time information is preserved by mapping the property to a <type>timestamp</type> converter,
which identifies an instance of the class <classname>org.hibernate.type.TimestampType</classname>.
</para>
@ -334,4 +334,4 @@ session.close();]]></programlisting>
</itemizedlist>
</section>
</chapter>
</chapter>

View File

@ -95,6 +95,7 @@ public class CacheDataDescriptionImpl implements CacheDataDescription {
if ( model.isVersioned() ) {
versionComparator = (
( VersionType ) model.getHierarchyDetails()
.getEntityVersion()
.getVersioningAttributeBinding()
.getHibernateTypeDescriptor()
.getResolvedTypeMapping()

View File

@ -226,7 +226,7 @@ public class Cache71Dialect extends Dialect {
protected final void commonRegistration() {
// Note: For object <-> SQL datatype mappings see:
// Configuration Manager | Advanced | SQL | System DDL Datatype Mappings
// Configuration Manager | Advanced | SQL | System DDL JdbcDataType Mappings
//
// TBD registerColumnType(Types.BINARY, "binary($1)");
// changed 08-11-2005, jsl

View File

@ -24,7 +24,7 @@
package org.hibernate.metamodel.internal.source.annotations.attribute;
import org.hibernate.TruthValue;
import org.hibernate.metamodel.spi.relational.Datatype;
import org.hibernate.metamodel.spi.relational.JdbcDataType;
import org.hibernate.metamodel.spi.relational.Size;
import org.hibernate.metamodel.spi.source.ColumnSource;
@ -68,7 +68,7 @@ public class ColumnValuesSourceImpl implements ColumnSource {
}
@Override
public Datatype getDatatype() {
public JdbcDataType getDatatype() {
return null;
}

View File

@ -66,6 +66,11 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem
return associationAttribute.getMappedBy();
}
@Override
public String getForeignKeyName() {
return null;
}
@Override
public Iterable<CascadeStyle> getCascadeStyles() {
return cascadeStyles;

View File

@ -0,0 +1,47 @@
/*
* 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.annotations.attribute;
import org.hibernate.metamodel.spi.source.VersionAttributeSource;
/**
* @author Steve Ebersole
*/
public class VersionAttributeSourceImpl
extends SingularAttributeSourceImpl
implements VersionAttributeSource {
public VersionAttributeSourceImpl(MappedAttribute attribute) {
super( attribute );
}
public VersionAttributeSourceImpl(MappedAttribute attribute, AttributeOverride attributeOverride) {
super( attribute, attributeOverride );
}
@Override
public String getUnsavedValue() {
return null;
}
}

View File

@ -27,15 +27,15 @@ import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.metamodel.spi.binding.Caching;
import org.hibernate.metamodel.internal.source.annotations.attribute.BasicAttribute;
import org.hibernate.metamodel.internal.source.annotations.attribute.DiscriminatorSourceImpl;
import org.hibernate.metamodel.internal.source.annotations.attribute.SimpleIdentifierSourceImpl;
import org.hibernate.metamodel.internal.source.annotations.attribute.SingularAttributeSourceImpl;
import org.hibernate.metamodel.internal.source.annotations.attribute.VersionAttributeSourceImpl;
import org.hibernate.metamodel.spi.binding.Caching;
import org.hibernate.metamodel.spi.source.DiscriminatorSource;
import org.hibernate.metamodel.spi.source.IdentifierSource;
import org.hibernate.metamodel.spi.source.RootEntitySource;
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
import org.hibernate.metamodel.spi.source.VersionAttributeSource;
/**
* @author Hardy Ferentschik
@ -66,13 +66,12 @@ public class RootEntitySourceImpl extends EntitySourceImpl implements RootEntity
}
@Override
public SingularAttributeSource getVersioningAttributeSource() {
SingularAttributeSource attributeSource = null;
EntityClass entityClass = getEntityClass();
if ( entityClass.getVersionAttribute() != null ) {
attributeSource = new SingularAttributeSourceImpl( entityClass.getVersionAttribute() );
public VersionAttributeSource getVersioningAttributeSource() {
final EntityClass entityClass = getEntityClass();
if ( entityClass.getVersionAttribute() == null ) {
return null;
}
return attributeSource;
return new VersionAttributeSourceImpl( entityClass.getVersionAttribute() );
}
@Override

View File

@ -31,16 +31,16 @@ import org.jboss.logging.Logger;
import org.hibernate.AnnotationException;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.ObjectName;
import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.metamodel.spi.source.MetadataImplementor;
import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.internal.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.internal.source.annotations.JandexHelper;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.Index;
import org.hibernate.metamodel.spi.relational.ObjectName;
import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.metamodel.spi.relational.Value;
import org.hibernate.metamodel.spi.source.MetadataImplementor;
/**
* Binds table related information. This binder is called after the entities are bound.
@ -120,7 +120,7 @@ public class TableProcessor {
private static Column findColumn(Table table, String columnName) {
Column column = null;
for ( SimpleValue value : table.values() ) {
for ( Value value : table.values() ) {
if ( value instanceof Column && ( (Column) value ).getColumnName().getName().equals( columnName ) ) {
column = (Column) value;
break;

View File

@ -24,7 +24,7 @@
package org.hibernate.metamodel.internal.source.hbm;
import org.hibernate.TruthValue;
import org.hibernate.metamodel.spi.relational.Datatype;
import org.hibernate.metamodel.spi.relational.JdbcDataType;
import org.hibernate.metamodel.spi.relational.Size;
import org.hibernate.metamodel.spi.source.ColumnSource;
@ -103,7 +103,7 @@ class ColumnAttributeSourceImpl implements ColumnSource {
}
@Override
public Datatype getDatatype() {
public JdbcDataType getDatatype() {
return null;
}

View File

@ -25,7 +25,7 @@ package org.hibernate.metamodel.internal.source.hbm;
import org.hibernate.TruthValue;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbColumnElement;
import org.hibernate.metamodel.spi.relational.Datatype;
import org.hibernate.metamodel.spi.relational.JdbcDataType;
import org.hibernate.metamodel.spi.relational.Size;
import org.hibernate.metamodel.spi.source.ColumnSource;
@ -86,7 +86,7 @@ class ColumnSourceImpl implements ColumnSource {
}
@Override
public Datatype getDatatype() {
public JdbcDataType getDatatype() {
return null;
}

View File

@ -268,4 +268,9 @@ class ManyToOneAttributeSourceImpl implements ToOneAttributeSource {
public String getReferencedEntityAttributeName() {
return manyToOneElement.getPropertyRef();
}
@Override
public String getForeignKeyName() {
return manyToOneElement.getForeignKey();
}
}

View File

@ -45,6 +45,7 @@ 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.TableSource;
import org.hibernate.metamodel.spi.source.VersionAttributeSource;
/**
* @author Steve Ebersole
@ -100,7 +101,7 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
}
@Override
public SingularAttributeSource getVersioningAttributeSource() {
public VersionAttributeSource getVersioningAttributeSource() {
if ( entityElement().getVersion() != null ) {
return new VersionAttributeSourceImpl(
entityElement().getVersion(),

View File

@ -29,20 +29,20 @@ import java.util.Map;
import org.hibernate.internal.jaxb.mapping.hbm.JaxbHibernateMapping;
import org.hibernate.internal.util.Value;
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.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;
import org.hibernate.metamodel.spi.source.VersionAttributeSource;
/**
* Implementation for {@code <timestamp/>} mappings
*
* @author Steve Ebersole
*/
class TimestampAttributeSourceImpl implements SingularAttributeSource {
class TimestampAttributeSourceImpl implements VersionAttributeSource {
private final JaxbHibernateMapping.JaxbClass.JaxbTimestamp timestampElement;
private final LocalBindingContext bindingContext;
private final List<RelationalValueSource> valueSources;
@ -193,4 +193,9 @@ class TimestampAttributeSourceImpl implements SingularAttributeSource {
public Iterable<MetaAttributeSource> metaAttributes() {
return Helper.buildMetaAttributeSources( timestampElement.getMeta() );
}
@Override
public String getUnsavedValue() {
return timestampElement.getUnsavedValue();
}
}

View File

@ -35,14 +35,15 @@ 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;
import org.hibernate.metamodel.spi.source.VersionAttributeSource;
/**
* Implementation for {@code <version/>} mappings
*
* @author Steve Ebersole
*/
class VersionAttributeSourceImpl implements SingularAttributeSource {
class VersionAttributeSourceImpl implements VersionAttributeSource {
private final JaxbHibernateMapping.JaxbClass.JaxbVersion versionElement;
private final LocalBindingContext bindingContext;
private final List<RelationalValueSource> valueSources;
@ -101,6 +102,11 @@ class VersionAttributeSourceImpl implements SingularAttributeSource {
}
};
@Override
public String getUnsavedValue() {
return versionElement.getUnsavedValue();
}
@Override
public String getName() {
return versionElement.getName();

View File

@ -42,17 +42,27 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final Set<SingularAssociationAttributeBinding> entityReferencingAttributeBindings = new HashSet<SingularAssociationAttributeBinding>();
private boolean includedInOptimisticLocking;
private final String propertyAccessorName;
private final boolean includedInOptimisticLocking;
private final boolean isLazy;
private boolean isLazy;
private String propertyAccessorName;
private boolean isAlternateUniqueKey;
private MetaAttributeContext metaAttributeContext;
private final MetaAttributeContext metaAttributeContext;
protected AbstractAttributeBinding(AttributeBindingContainer container, Attribute attribute) {
protected AbstractAttributeBinding(
AttributeBindingContainer container,
Attribute attribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean isLazy,
MetaAttributeContext metaAttributeContext) {
this.container = container;
this.attribute = attribute;
this.propertyAccessorName = propertyAccessorName;
this.includedInOptimisticLocking = includedInOptimisticLocking;
this.isLazy = isLazy;
this.metaAttributeContext = metaAttributeContext;
}
@Override
@ -84,30 +94,19 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
return propertyAccessorName;
}
public void setPropertyAccessorName(String propertyAccessorName) {
this.propertyAccessorName = propertyAccessorName;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return includedInOptimisticLocking;
}
public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking) {
this.includedInOptimisticLocking = includedInOptimisticLocking;
}
@Override
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}
public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) {
this.metaAttributeContext = metaAttributeContext;
}
@Override
public boolean isAlternateUniqueKey() {
// todo : is this the same as "part of natural id"?
return isAlternateUniqueKey;
}
@ -120,10 +119,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
return isLazy;
}
public void setLazy(boolean isLazy) {
this.isLazy = isLazy;
}
public void addEntityReferencingAttributeBinding(SingularAssociationAttributeBinding referencingAttributeBinding) {
entityReferencingAttributeBindings.add( referencingAttributeBinding );
}

View File

@ -34,6 +34,7 @@ import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
import org.hibernate.persister.collection.CollectionPersister;
/**
@ -56,7 +57,7 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi
private boolean mutable = true;
private Class<? extends CollectionPersister> collectionPersisterClass;
private Class<? extends CollectionPersister> explicitPersisterClass;
private String where;
private String orderBy;
@ -78,8 +79,19 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi
protected AbstractPluralAttributeBinding(
AttributeBindingContainer container,
PluralAttribute attribute,
PluralAttributeElementNature pluralAttributeElementNature) {
super( container, attribute );
PluralAttributeElementNature pluralAttributeElementNature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean isLazy,
MetaAttributeContext metaAttributeContext) {
super(
container,
attribute,
propertyAccessorName,
includedInOptimisticLocking,
isLazy,
metaAttributeContext
);
this.pluralAttributeKeyBinding = new PluralAttributeKeyBinding( this );
this.pluralAttributeElementBinding = interpretNature( pluralAttributeElementNature );
}
@ -214,12 +226,13 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi
this.customSqlDeleteAll = customSqlDeleteAll;
}
public Class<? extends CollectionPersister> getCollectionPersisterClass() {
return collectionPersisterClass;
@Override
public Class<? extends CollectionPersister> getExplicitPersisterClass() {
return explicitPersisterClass;
}
public void setCollectionPersisterClass(Class<? extends CollectionPersister> collectionPersisterClass) {
this.collectionPersisterClass = collectionPersisterClass;
public void setExplicitPersisterClass(Class<? extends CollectionPersister> explicitPersisterClass) {
this.explicitPersisterClass = explicitPersisterClass;
}
public Caching getCaching() {

View File

@ -23,14 +23,10 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.Tuple;
import org.hibernate.metamodel.spi.relational.Value;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* @author Steve Ebersole
@ -39,14 +35,14 @@ public abstract class AbstractSingularAttributeBinding
extends AbstractAttributeBinding
implements SingularAttributeBinding {
private Value value;
private List<SimpleValueBinding> simpleValueBindings = new ArrayList<SimpleValueBinding>();
private boolean hasDerivedValue;
private boolean isNullable = true;
protected AbstractSingularAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) {
super( container, attribute );
protected AbstractSingularAttributeBinding(
AttributeBindingContainer container,
SingularAttribute attribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext) {
super( container, attribute, propertyAccessorName, includedInOptimisticLocking, lazy, metaAttributeContext );
}
@Override
@ -54,56 +50,5 @@ public abstract class AbstractSingularAttributeBinding
return (SingularAttribute) super.getAttribute();
}
public Value getValue() {
return value;
}
public void setSimpleValueBindings(Iterable<SimpleValueBinding> simpleValueBindings) {
List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( SimpleValueBinding simpleValueBinding : simpleValueBindings ) {
this.simpleValueBindings.add( simpleValueBinding );
values.add( simpleValueBinding.getSimpleValue() );
this.hasDerivedValue = this.hasDerivedValue || simpleValueBinding.isDerived();
this.isNullable = this.isNullable && simpleValueBinding.isNullable();
}
if ( values.size() == 1 ) {
this.value = values.get( 0 );
}
else {
final Tuple tuple = values.get( 0 ).getTable().createTuple( getRole() );
for ( SimpleValue value : values ) {
tuple.addValue( value );
}
this.value = tuple;
}
}
@Override
public int getSimpleValueSpan() {
checkValueBinding();
return simpleValueBindings.size();
}
protected void checkValueBinding() {
if ( value == null ) {
throw new AssertionFailure( "No values yet bound!" );
}
}
@Override
public Iterable<SimpleValueBinding> getSimpleValueBindings() {
return simpleValueBindings;
}
@Override
public boolean hasDerivedValue() {
checkValueBinding();
return hasDerivedValue;
}
@Override
public boolean isNullable() {
checkValueBinding();
return isNullable;
}
protected abstract void collectRelationalValueBindings(List<RelationalValueBinding> valueBindings);
}

View File

@ -64,12 +64,8 @@ public interface AttributeBinding {
public String getPropertyAccessorName();
public void setPropertyAccessorName(String propertyAccessorName);
public boolean isIncludedInOptimisticLocking();
public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking);
/**
* Obtain the meta attributes associated with this binding
*

View File

@ -23,9 +23,14 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.Comparator;
import java.util.List;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.domain.AttributeContainer;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.ForeignKey;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
@ -72,7 +77,14 @@ public interface AttributeBindingContainer {
*
* @return The attribute binding instance.
*/
public BasicAttributeBinding makeBasicAttributeBinding(SingularAttribute attribute);
public BasicAttributeBinding makeBasicAttributeBinding(
SingularAttribute attribute,
List<RelationalValueBinding> relationalValueBindings,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
PropertyGeneration generation);
/**
* Factory method for component attribute bindings.
@ -81,16 +93,33 @@ public interface AttributeBindingContainer {
*
* @return The attribute binding instance.
*/
public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute);
public ComponentAttributeBinding makeComponentAttributeBinding(
SingularAttribute attribute,
SingularAttribute parentReferenceAttribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext);
/**
* Factory method for many-to-one attribute bindings.
*
*
* @param attribute The attribute for which to make a binding.
* @param referencedEntityName
* @param referencedEntityAttributeName
*
* @return The attribute binding instance.
*/
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute);
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(
SingularAttribute attribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
String referencedEntityName,
String referencedEntityAttributeName,
List<RelationalValueBinding> valueBindings);
/**
* Factory method for bag attribute bindings.
@ -100,7 +129,13 @@ public interface AttributeBindingContainer {
*
* @return The attribute binding instance.
*/
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, PluralAttributeElementNature nature);
public BagBinding makeBagAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementNature nature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext);
/**
* Factory method for bag attribute bindings.
@ -110,7 +145,14 @@ public interface AttributeBindingContainer {
*
* @return The attribute binding instance.
*/
public SetBinding makeSetAttributeBinding(PluralAttribute attribute, PluralAttributeElementNature nature);
public SetBinding makeSetAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementNature nature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
Comparator comparator);
/**
* Seeks out the entity binding that is the root of this component path.

View File

@ -24,6 +24,7 @@
package org.hibernate.metamodel.spi.binding;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* TODO : javadoc
@ -31,7 +32,22 @@ import org.hibernate.metamodel.spi.domain.PluralAttribute;
* @author Steve Ebersole
*/
public class BagBinding extends AbstractPluralAttributeBinding {
protected BagBinding(AttributeBindingContainer container, PluralAttribute attribute, PluralAttributeElementNature nature) {
super( container, attribute, nature );
protected BagBinding(
AttributeBindingContainer container,
PluralAttribute attribute,
PluralAttributeElementNature pluralAttributeElementNature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean isLazy,
MetaAttributeContext metaAttributeContext) {
super(
container,
attribute,
pluralAttributeElementNature,
propertyAccessorName,
includedInOptimisticLocking,
isLazy,
metaAttributeContext
);
}
}

View File

@ -23,6 +23,8 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.hibernate.MappingException;
@ -33,36 +35,45 @@ import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* TODO : javadoc
* TODO : this really needs an overhaul... mainly, get rid of the KeyValueBinding concept...
*
* @author Steve Ebersole
*/
public class BasicAttributeBinding
extends AbstractSingularAttributeBinding
implements KeyValueBinding {
extends AbstractSingularAttributeBinding {
private String unsavedValue;
private PropertyGeneration generation;
private boolean includedInOptimisticLocking;
private boolean forceNonNullable;
private boolean forceUnique;
private boolean keyCascadeDeleteEnabled;
private MetaAttributeContext metaAttributeContext;
private final List<RelationalValueBinding> relationalValueBindings;
private boolean hasDerivedValue;
private boolean isNullable = true;
private final PropertyGeneration generation;
BasicAttributeBinding(
AttributeBindingContainer container,
SingularAttribute attribute,
boolean forceNonNullable,
boolean forceUnique) {
super( container, attribute );
this.forceNonNullable = forceNonNullable;
this.forceUnique = forceUnique;
List<RelationalValueBinding> relationalValueBindings,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
PropertyGeneration generation) {
super(
container,
attribute,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext
);
this.relationalValueBindings = Collections.unmodifiableList( relationalValueBindings );
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
this.hasDerivedValue = this.hasDerivedValue || relationalValueBinding.isDerived();
this.isNullable = this.isNullable && relationalValueBinding.isNullable();
}
this.generation = generation;
}
@Override
@ -70,68 +81,50 @@ public class BasicAttributeBinding
return false;
}
@Override
public String getUnsavedValue() {
return unsavedValue;
}
public void setUnsavedValue(String unsavedValue) {
this.unsavedValue = unsavedValue;
public List<RelationalValueBinding> getRelationalValueBindings() {
return relationalValueBindings;
}
@Override
public boolean hasDerivedValue() {
return hasDerivedValue;
}
@Override
public boolean isNullable() {
return isNullable;
}
public PropertyGeneration getGeneration() {
return generation;
}
public void setGeneration(PropertyGeneration generation) {
this.generation = generation;
}
public boolean isIncludedInOptimisticLocking() {
return includedInOptimisticLocking;
}
public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking) {
this.includedInOptimisticLocking = includedInOptimisticLocking;
}
@Override
public boolean isKeyCascadeDeleteEnabled() {
return keyCascadeDeleteEnabled;
}
public void setKeyCascadeDeleteEnabled(boolean keyCascadeDeleteEnabled) {
this.keyCascadeDeleteEnabled = keyCascadeDeleteEnabled;
}
public boolean forceNonNullable() {
return forceNonNullable;
}
public boolean forceUnique() {
return forceUnique;
}
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}
public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) {
this.metaAttributeContext = metaAttributeContext;
}
IdentifierGenerator createIdentifierGenerator(
IdGenerator idGenerator,
IdentifierGeneratorFactory identifierGeneratorFactory,
Properties properties) {
if ( getRelationalValueBindings().size() > 1 ) {
throw new MappingException(
"A SimpleAttributeBinding used for an identifier has more than 1 Value: " + getAttribute().getName()
);
}
final RelationalValueBinding relationalValueBinding = getRelationalValueBindings().get( 0 );
final TableSpecification table = relationalValueBinding.getValue().getTable();
if ( !Column.class.isInstance( relationalValueBinding.getValue() ) ) {
throw new MappingException(
"Cannot create an IdentifierGenerator because the value is not a column: " +
relationalValueBinding.getValue().toLoggableString()
);
}
Properties params = new Properties();
params.putAll( properties );
// use the schema/catalog specified by getValue().getTable() - but note that
// if the schema/catalog were specified as params, they will already be initialized and
//will override the values set here (they are in idGenerator.getParameters().)
Schema schema = getValue().getTable().getSchema();
Schema schema = table.getSchema();
if ( schema != null ) {
if ( schema.getName().getSchema() != null ) {
params.setProperty( PersistentIdentifierGenerator.SCHEMA, schema.getName().getSchema().getName() );
@ -141,57 +134,29 @@ public class BasicAttributeBinding
}
}
// TODO: not sure how this works for collection IDs...
//pass the entity-name, if not a collection-id
//if ( rootClass!=null) {
params.setProperty( IdentifierGenerator.ENTITY_NAME, getContainer().seekEntityBinding().getEntity().getName() );
//}
params.setProperty( IdentifierGenerator.ENTITY_NAME, getContainer().seekEntityBinding().getEntity().getName() );
//init the table here instead of earlier, so that we can get a quoted table name
//TODO: would it be better to simply pass the qualified table name, instead of
// splitting it up into schema/catalog/table names
String tableName = getValue().getTable().getQualifiedName( identifierGeneratorFactory.getDialect() );
String tableName = table.getQualifiedName( identifierGeneratorFactory.getDialect() );
params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
//pass the column name (a generated id almost always has a single column)
if ( getSimpleValueSpan() > 1 ) {
throw new MappingException(
"A SimpleAttributeBinding used for an identifier has more than 1 Value: " + getAttribute().getName()
);
}
SimpleValue simpleValue = (SimpleValue) getValue();
if ( !Column.class.isInstance( simpleValue ) ) {
throw new MappingException(
"Cannot create an IdentifierGenerator because the value is not a column: " +
simpleValue.toLoggableString()
);
}
params.setProperty(
PersistentIdentifierGenerator.PK,
( (Column) simpleValue ).getColumnName().encloseInQuotesIfQuoted(
( (Column) relationalValueBinding.getValue() ).getColumnName().encloseInQuotesIfQuoted(
identifierGeneratorFactory.getDialect()
)
);
// TODO: is this stuff necessary for SimpleValue???
//if (rootClass!=null) {
// StringBuffer tables = new StringBuffer();
// Iterator iter = rootClass.getIdentityTables().iterator();
// while ( iter.hasNext() ) {
// Table table= (Table) iter.next();
// tables.append( table.getQuotedName(dialect) );
// if ( iter.hasNext() ) tables.append(", ");
// }
// params.setProperty( PersistentIdentifierGenerator.TABLES, tables.toString() );
//}
//else {
params.setProperty( PersistentIdentifierGenerator.TABLES, tableName );
//}
params.putAll( idGenerator.getParameters() );
return identifierGeneratorFactory.createIdentifierGenerator(
idGenerator.getStrategy(), getHibernateTypeDescriptor().getResolvedTypeMapping(), params
);
}
@Override
protected void collectRelationalValueBindings(List<RelationalValueBinding> valueBindings) {
valueBindings.addAll( relationalValueBindings );
}
}

View File

@ -23,13 +23,9 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.Tuple;
import org.hibernate.metamodel.spi.relational.Value;
/**
* Describes plural attributes of {@link PluralAttributeElementNature#BASIC} elements
*
@ -37,8 +33,7 @@ import org.hibernate.metamodel.spi.relational.Value;
* @author Gail Badner
*/
public class BasicPluralAttributeElementBinding extends AbstractPluralAttributeElementBinding {
private Value value;
private List<SimpleValueBinding> simpleValueBindings = new ArrayList<SimpleValueBinding>();
private List<RelationalValueBinding> relationalValueBindings;
private boolean hasDerivedValue;
private boolean isNullable = true;
@ -46,29 +41,21 @@ public class BasicPluralAttributeElementBinding extends AbstractPluralAttributeE
public BasicPluralAttributeElementBinding(AbstractPluralAttributeBinding binding) {
super( binding );
}
public List<RelationalValueBinding> getRelationalValueBindings() {
return relationalValueBindings;
}
@Override
public PluralAttributeElementNature getPluralAttributeElementNature() {
return PluralAttributeElementNature.BASIC;
}
public void setSimpleValueBindings(Iterable<SimpleValueBinding> simpleValueBindings) {
List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( SimpleValueBinding simpleValueBinding : simpleValueBindings ) {
this.simpleValueBindings.add( simpleValueBinding );
values.add( simpleValueBinding.getSimpleValue() );
this.hasDerivedValue = this.hasDerivedValue || simpleValueBinding.isDerived();
this.isNullable = this.isNullable && simpleValueBinding.isNullable();
}
if ( values.size() == 1 ) {
this.value = values.get( 0 );
}
else {
final Tuple tuple = values.get( 0 ).getTable().createTuple( getPluralAttributeBinding().getRole() );
for ( SimpleValue value : values ) {
tuple.addValue( value );
}
this.value = tuple;
public void setRelationalValueBindings(List<RelationalValueBinding> relationalValueBindings) {
this.relationalValueBindings = Collections.unmodifiableList( relationalValueBindings );
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
this.hasDerivedValue = this.hasDerivedValue || relationalValueBinding.isDerived();
this.isNullable = this.isNullable && relationalValueBinding.isNullable();
}
}
}

View File

@ -23,7 +23,10 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.mapping.PropertyGeneration;
@ -32,22 +35,55 @@ import org.hibernate.metamodel.spi.domain.Component;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.domain.PluralAttributeNature;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.ForeignKey;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* @author Steve Ebersole
*/
public class ComponentAttributeBinding extends AbstractSingularAttributeBinding implements AttributeBindingContainer {
public class ComponentAttributeBinding
extends AbstractSingularAttributeBinding
implements AttributeBindingContainer {
private final String path;
private final SingularAttribute parentReference;
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
private SingularAttribute parentReference;
private MetaAttributeContext metaAttributeContext;
public ComponentAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) {
super( container, attribute );
public ComponentAttributeBinding(
AttributeBindingContainer container,
SingularAttribute attribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
SingularAttribute parentReference) {
super(
container,
attribute,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext
);
this.parentReference = parentReference;
this.path = container.getPathBase() + '.' + attribute.getName();
}
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
final List<RelationalValueBinding> bindings = new ArrayList<RelationalValueBinding>();
collectRelationalValueBindings( bindings );
return bindings;
}
@Override
protected void collectRelationalValueBindings(List<RelationalValueBinding> valueBindings) {
for ( AttributeBinding subAttributeBinding : attributeBindings() ) {
if ( AbstractSingularAttributeBinding.class.isInstance( subAttributeBinding ) ) {
( (AbstractSingularAttributeBinding) subAttributeBinding ).collectRelationalValueBindings( valueBindings );
}
}
}
@Override
public EntityBinding seekEntityBinding() {
return getContainer().seekEntityBinding();
@ -73,12 +109,15 @@ public class ComponentAttributeBinding extends AbstractSingularAttributeBinding
}
@Override
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
public boolean hasDerivedValue() {
// todo : not sure this is even relevant for components
return false;
}
public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) {
this.metaAttributeContext = metaAttributeContext;
@Override
public boolean isNullable() {
// todo : not sure this is even relevant for components
return false;
}
@Override
@ -92,17 +131,23 @@ public class ComponentAttributeBinding extends AbstractSingularAttributeBinding
}
@Override
protected void checkValueBinding() {
// do nothing here...
}
@Override
public BasicAttributeBinding makeBasicAttributeBinding(SingularAttribute attribute) {
public BasicAttributeBinding makeBasicAttributeBinding(
SingularAttribute attribute,
List<RelationalValueBinding> relationalValueBindings,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
PropertyGeneration generation) {
final BasicAttributeBinding binding = new BasicAttributeBinding(
this,
attribute,
isNullable(),
isAlternateUniqueKey() // todo : is this accurate?
relationalValueBindings,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext,
generation
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
@ -114,31 +159,91 @@ public class ComponentAttributeBinding extends AbstractSingularAttributeBinding
}
@Override
public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute) {
final ComponentAttributeBinding binding = new ComponentAttributeBinding( this, attribute );
public ComponentAttributeBinding makeComponentAttributeBinding(
SingularAttribute attribute,
SingularAttribute parentReferenceAttribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext) {
final ComponentAttributeBinding binding = new ComponentAttributeBinding(
this,
attribute,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext,
parentReferenceAttribute
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute );
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(
SingularAttribute attribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
String referencedEntityName,
String referencedEntityAttributeName,
List<RelationalValueBinding> valueBindings) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding(
this,
attribute,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext,
valueBindings
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, PluralAttributeElementNature nature) {
public BagBinding makeBagAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementNature nature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext) {
Helper.checkPluralAttributeNature( attribute, PluralAttributeNature.BAG );
final BagBinding binding = new BagBinding( this, attribute, nature );
final BagBinding binding = new BagBinding(
this,
attribute,
nature,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public SetBinding makeSetAttributeBinding(PluralAttribute attribute, PluralAttributeElementNature nature) {
public SetBinding makeSetAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementNature nature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
Comparator comparator) {
Helper.checkPluralAttributeNature( attribute, PluralAttributeNature.SET );
final SetBinding binding = new SetBinding( this, attribute, nature );
final SetBinding binding = new SetBinding(
this,
attribute,
nature,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext,
comparator
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@ -151,14 +256,4 @@ public class ComponentAttributeBinding extends AbstractSingularAttributeBinding
public SingularAttribute getParentReference() {
return parentReference;
}
public void setParentReference(SingularAttribute parentReference) {
this.parentReference = parentReference;
}
@Override
public PropertyGeneration getGeneration() {
// todo : not sure the correct thing to return here since it essentially relies on the simple sub-attributes.
return null;
}
}

View File

@ -24,6 +24,7 @@
package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -35,6 +36,7 @@ import org.hibernate.EntityMode;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.util.Value;
import org.hibernate.internal.util.collections.JoinedIterable;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.domain.AttributeContainer;
import org.hibernate.metamodel.spi.domain.Entity;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
@ -257,7 +259,7 @@ public class EntityBinding implements AttributeBindingContainer {
}
public boolean isVersioned() {
return getHierarchyDetails().getVersioningAttributeBinding() != null;
return getHierarchyDetails().getEntityVersion().getVersioningAttributeBinding() != null;
}
public boolean isDiscriminatorMatchValueNull() {
@ -487,47 +489,114 @@ public class EntityBinding implements AttributeBindingContainer {
}
@Override
public BasicAttributeBinding makeBasicAttributeBinding(SingularAttribute attribute) {
return makeSimpleAttributeBinding( attribute, false, false );
}
private BasicAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute, boolean forceNonNullable, boolean forceUnique) {
public BasicAttributeBinding makeBasicAttributeBinding(
SingularAttribute attribute,
List<RelationalValueBinding> relationalValueBindings,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
PropertyGeneration generation) {
final BasicAttributeBinding binding = new BasicAttributeBinding(
this,
attribute,
forceNonNullable,
forceUnique
relationalValueBindings,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext,
generation
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute) {
final ComponentAttributeBinding binding = new ComponentAttributeBinding( this, attribute );
public ComponentAttributeBinding makeComponentAttributeBinding(
SingularAttribute attribute,
SingularAttribute parentReferenceAttribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext) {
final ComponentAttributeBinding binding = new ComponentAttributeBinding(
this,
attribute,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext,
parentReferenceAttribute
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute );
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(
SingularAttribute attribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
String referencedEntityName,
String referencedEntityAttributeName,
List<RelationalValueBinding> valueBindings) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding(
this,
attribute,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext,
valueBindings
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, PluralAttributeElementNature nature) {
public BagBinding makeBagAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementNature nature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext) {
Helper.checkPluralAttributeNature( attribute, PluralAttributeNature.BAG );
final BagBinding binding = new BagBinding( this, attribute, nature );
final BagBinding binding = new BagBinding(
this,
attribute,
nature,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public SetBinding makeSetAttributeBinding(PluralAttribute attribute, PluralAttributeElementNature nature) {
public SetBinding makeSetAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementNature nature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
Comparator comparator) {
Helper.checkPluralAttributeNature( attribute, PluralAttributeNature.SET );
final SetBinding binding = new SetBinding( this, attribute, nature );
final SetBinding binding = new SetBinding(
this,
attribute,
nature,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext,
comparator
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@ -602,4 +671,5 @@ public class EntityBinding implements AttributeBindingContainer {
public Iterable<JpaCallbackSource> getJpaCallbackClasses() {
return jpaCallbackClasses;
}
}

View File

@ -23,7 +23,7 @@
*/
package org.hibernate.metamodel.spi.binding;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.Value;
/**
* Binding of the discriminator in a entity hierarchy
@ -34,19 +34,18 @@ import org.hibernate.metamodel.spi.relational.SimpleValue;
public class EntityDiscriminator {
private final HibernateTypeDescriptor explicitHibernateTypeDescriptor = new HibernateTypeDescriptor();
private SimpleValue boundValue;
private boolean forced;
private boolean inserted = true;
private final Value relationalValue;
private final boolean inserted;
private final boolean forced;
public EntityDiscriminator() {
public EntityDiscriminator(Value relationalValue, boolean inserted, boolean forced) {
this.relationalValue = relationalValue;
this.inserted = inserted;
this.forced = forced;
}
public SimpleValue getBoundValue() {
return boundValue;
}
public void setBoundValue(SimpleValue boundValue) {
this.boundValue = boundValue;
public Value getRelationalValue() {
return relationalValue;
}
public HibernateTypeDescriptor getExplicitHibernateTypeDescriptor() {
@ -57,23 +56,15 @@ public class EntityDiscriminator {
return forced;
}
public void setForced(boolean forced) {
this.forced = forced;
}
public boolean isInserted() {
return inserted;
}
public void setInserted(boolean inserted) {
this.inserted = inserted;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "EntityDiscriminator" );
sb.append( "{boundValue=" ).append( boundValue );
sb.append( "{relationalValue=" ).append( relationalValue );
sb.append( ", forced=" ).append( forced );
sb.append( ", inserted=" ).append( inserted );
sb.append( '}' );

View File

@ -42,6 +42,7 @@ public class EntityIdentifier {
private IdGenerator idGenerator;
private boolean isIdentifierMapper = false;
// todo : mappers, etc
private String unsavedValue;
/**
* Create an identifier
@ -73,7 +74,7 @@ public class EntityIdentifier {
}
public boolean isEmbedded() {
return attributeBinding.getSimpleValueSpan() > 1;
return attributeBinding.getRelationalValueBindings().size() > 1;
}
public boolean isIdentifierMapper() {
@ -92,4 +93,12 @@ public class EntityIdentifier {
public IdentifierGenerator getIdentifierGenerator() {
return identifierGenerator;
}
public String getUnsavedValue() {
return unsavedValue;
}
public void setUnsavedValue(String unsavedValue) {
this.unsavedValue = unsavedValue;
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.source.EntityHierarchy;
/**
* @author Steve Ebersole
*/
public class EntityVersion {
private final EntityBinding rootEntityBinding;
private BasicAttributeBinding versioningAttributeBinding;
private String unsavedValue;
public EntityVersion(EntityBinding rootEntityBinding) {
this.rootEntityBinding = rootEntityBinding;
}
public BasicAttributeBinding getVersioningAttributeBinding() {
return versioningAttributeBinding;
}
public void setVersioningAttributeBinding(BasicAttributeBinding versioningAttributeBinding) {
this.versioningAttributeBinding = versioningAttributeBinding;
}
public String getUnsavedValue() {
return unsavedValue;
}
public void setUnsavedValue(String unsavedValue) {
this.unsavedValue = unsavedValue;
}
}

View File

@ -39,7 +39,7 @@ public class HierarchyDetails {
private EntityDiscriminator entityDiscriminator;
private OptimisticLockStyle optimisticLockStyle;
private BasicAttributeBinding versioningAttributeBinding;
private EntityVersion entityVersion;
private Caching caching;
@ -50,6 +50,7 @@ public class HierarchyDetails {
this.inheritanceType = inheritanceType;
this.entityMode = entityMode;
this.entityIdentifier = new EntityIdentifier( rootEntityBinding );
this.entityVersion = new EntityVersion( rootEntityBinding );
}
public EntityBinding getRootEntityBinding() {
@ -84,12 +85,12 @@ public class HierarchyDetails {
this.entityDiscriminator = entityDiscriminator;
}
public BasicAttributeBinding getVersioningAttributeBinding() {
return versioningAttributeBinding;
public EntityVersion getEntityVersion() {
return entityVersion;
}
public void setVersioningAttributeBinding(BasicAttributeBinding versioningAttributeBinding) {
this.versioningAttributeBinding = versioningAttributeBinding;
public void setEntityVersion(EntityVersion entityVersion) {
this.entityVersion = entityVersion;
}
public Caching getCaching() {

View File

@ -24,6 +24,7 @@
package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.AssertionFailure;
@ -32,6 +33,7 @@ import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* TODO : javadoc
@ -39,20 +41,56 @@ import org.hibernate.metamodel.spi.domain.SingularAttribute;
* @author Gail Badner
* @author Steve Ebersole
*/
public class ManyToOneAttributeBinding extends BasicAttributeBinding implements SingularAssociationAttributeBinding {
public class ManyToOneAttributeBinding
extends AbstractSingularAttributeBinding
implements SingularAssociationAttributeBinding {
private final List<RelationalValueBinding> relationalValueBindings;
private String referencedEntityName;
private String referencedAttributeName;
private AttributeBinding referencedAttributeBinding;
private boolean isLogicalOneToOne;
private String foreignKeyName;
private CascadeStyle cascadeStyle;
private FetchTiming fetchTiming;
private FetchStyle fetchStyle;
ManyToOneAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) {
super( container, attribute, false, false );
public ManyToOneAttributeBinding(
AttributeBindingContainer container,
SingularAttribute attribute,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean lazy,
MetaAttributeContext metaAttributeContext,
List<RelationalValueBinding> relationalValueBindings) {
super(
container,
attribute,
propertyAccessorName,
includedInOptimisticLocking,
lazy,
metaAttributeContext
);
this.relationalValueBindings = Collections.unmodifiableList( relationalValueBindings );
}
@Override
public List<RelationalValueBinding> getRelationalValueBindings() {
return relationalValueBindings;
}
@Override
public boolean hasDerivedValue() {
// todo : not sure this is even relevant for many-to-one
return false;
}
@Override
public boolean isNullable() {
// todo : not sure this is even relevant for many-to-one
return false;
}
@Override
@ -237,4 +275,9 @@ public class ManyToOneAttributeBinding extends BasicAttributeBinding implements
// }
// //TODO: validate that the entity reference is resolved
// }
@Override
protected void collectRelationalValueBindings(List<RelationalValueBinding> valueBindings) {
valueBindings.addAll( relationalValueBindings );
}
}

View File

@ -63,7 +63,7 @@ public interface PluralAttributeBinding extends AttributeBinding, Fetchable {
public Caching getCaching();
public Class<? extends CollectionPersister> getCollectionPersisterClass();
public Class<? extends CollectionPersister> getExplicitPersisterClass();
public String getCustomLoaderName();

View File

@ -25,7 +25,6 @@ package org.hibernate.metamodel.spi.binding;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.spi.relational.ForeignKey;
import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.metamodel.spi.relational.TableSpecification;
/**
@ -99,12 +98,17 @@ public class PluralAttributeKeyBinding {
throw new AssertionFailure( "Collection table not yet bound" );
}
if ( foreignKeyName != null ) {
foreignKey = collectionTable.locateForeignKey( foreignKeyName );
if ( foreignKey != null ) {
return;
}
}
final TableSpecification targetTable = pluralAttributeBinding.getContainer()
.seekEntityBinding()
.locateTable( targetTableName );
// todo : handle implicit fk names...
foreignKey = collectionTable.createForeignKey( targetTable, foreignKeyName );
}

View File

@ -25,60 +25,67 @@ package org.hibernate.metamodel.spi.binding;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.DerivedValue;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.Value;
/**
* Represents the binding information of a column/formula.
*
* Different from a {@link Value} because, while the {@link Value} exists only once in the relational model,
* that {@link Value} may be bound to multiple attributes. A {@link RelationalValueBinding} then tracks the
* information that is specific to each attribute's binding to that {@link Value}.
*
* @author Steve Ebersole
*/
public class SimpleValueBinding {
private SimpleValue simpleValue;
public class RelationalValueBinding {
private final Value value;
private boolean includeInInsert;
private boolean includeInUpdate;
public SimpleValueBinding() {
this( true, true );
public RelationalValueBinding(Value value) {
this( value, true, true );
}
public SimpleValueBinding(SimpleValue simpleValue) {
this();
setSimpleValue( simpleValue );
}
public SimpleValueBinding(SimpleValue simpleValue, boolean includeInInsert, boolean includeInUpdate) {
this( includeInInsert, includeInUpdate );
setSimpleValue( simpleValue );
}
public SimpleValueBinding(boolean includeInInsert, boolean includeInUpdate) {
this.includeInInsert = includeInInsert;
this.includeInUpdate = includeInUpdate;
}
public SimpleValue getSimpleValue() {
return simpleValue;
}
public void setSimpleValue(SimpleValue simpleValue) {
this.simpleValue = simpleValue;
if ( DerivedValue.class.isInstance( simpleValue ) ) {
includeInInsert = false;
includeInUpdate = false;
public RelationalValueBinding(Value value, boolean includeInInsert, boolean includeInUpdate) {
this.value = value;
if ( DerivedValue.class.isInstance( value ) ) {
this.includeInInsert = false;
this.includeInUpdate = false;
}
else {
this.includeInInsert = includeInInsert;
this.includeInUpdate = includeInUpdate;
}
}
public boolean isDerived() {
return DerivedValue.class.isInstance( simpleValue );
/**
* Retrieve the relational value bound here.
*
* @return The relational value.
*/
public Value getValue() {
return value;
}
/**
* Is the value bound here derived? Same as checking {@link #getValue()} as a {@link DerivedValue}
*
* @return {@code true} indicates the bound value is derived.
*/
public boolean isDerived() {
return DerivedValue.class.isInstance( value );
}
/**
* Is the value bound here nullable?
*
* @return {@code true} indicates the bound value is derived or a column not marked as non-null.
*/
public boolean isNullable() {
return isDerived() || Column.class.cast( simpleValue ).isNullable();
return isDerived() || Column.class.cast( value ).isNullable();
}
/**
* Is the value to be inserted as part of its binding here?
* <p/>
* <b>NOTE</b> that a column may be bound to multiple attributes. The purpose of this value is to track this
* notion of "insertability" for this particular binding.
*
* @return {@code true} indicates the value should be included; {@code false} indicates it should not
*/
@ -86,15 +93,12 @@ public class SimpleValueBinding {
return includeInInsert;
}
public void setIncludeInInsert(boolean includeInInsert) {
this.includeInInsert = includeInInsert;
}
/**
* Is the value to be updated as part of its binding here?
*
* @return {@code true} indicates the value should be included; {@code false} indicates it should not
*/
public boolean isIncludeInUpdate() {
return includeInUpdate;
}
public void setIncludeInUpdate(boolean includeInUpdate) {
this.includeInUpdate = includeInUpdate;
}
}

View File

@ -26,25 +26,36 @@ package org.hibernate.metamodel.spi.binding;
import java.util.Comparator;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* @author Steve Ebersole
*/
public class SetBinding extends AbstractPluralAttributeBinding {
private Comparator comparator;
private final Comparator comparator;
protected SetBinding(
public SetBinding(
AttributeBindingContainer container,
PluralAttribute attribute,
PluralAttributeElementNature pluralAttributeElementNature) {
super( container, attribute, pluralAttributeElementNature );
PluralAttributeElementNature pluralAttributeElementNature,
String propertyAccessorName,
boolean includedInOptimisticLocking,
boolean isLazy,
MetaAttributeContext metaAttributeContext,
Comparator comparator) {
super(
container,
attribute,
pluralAttributeElementNature,
propertyAccessorName,
includedInOptimisticLocking,
isLazy,
metaAttributeContext
);
this.comparator = comparator;
}
public Comparator getComparator() {
return comparator;
}
public void setComparator(Comparator comparator) {
this.comparator = comparator;
}
}

View File

@ -23,8 +23,10 @@
*/
package org.hibernate.metamodel.spi.binding;
import java.util.List;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.relational.Value;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
/**
* Specialized binding contract for singular (non-collection) attributes
@ -32,33 +34,14 @@ import org.hibernate.metamodel.spi.relational.Value;
* @author Steve Ebersole
*/
public interface SingularAttributeBinding extends AttributeBinding {
/**
* Obtain the value bound here. This could potentially be a {@link org.hibernate.metamodel.spi.relational.Tuple}
* indicating multiple database values are bound, in which case access to the individual values can be achieved by
* either casting this return to {@link org.hibernate.metamodel.spi.relational.Tuple} and using its
* {@link org.hibernate.metamodel.spi.relational.Tuple#values()} method or using the {@link #getSimpleValueBindings()}
* method here and accessing each bindings {@link SimpleValueBinding#getSimpleValue simple value}
*
* @return The bound value
*/
public Value getValue();
@Override
public SingularAttribute getAttribute();
public List<RelationalValueBinding> getRelationalValueBindings();
/**
* Returns the number of {@link SimpleValueBinding} objects that will be returned by
* {@link #getSimpleValueBindings()}
*
* @return the number of {@link SimpleValueBinding simple value bindings}
*
* @see #getSimpleValueBindings()
*/
public int getSimpleValueSpan();
public Iterable<SimpleValueBinding> getSimpleValueBindings();
public void setSimpleValueBindings(Iterable<SimpleValueBinding> simpleValueBindings);
/**
* Convenience method to determine if any {@link SimpleValueBinding simple value bindings} are derived values
* Convenience method to determine if any {@link RelationalValueBinding simple value bindings} are derived values
* (formula mappings).
*
* @return {@code true} indicates that the binding contains a derived value; {@code false} indicates it does not.
@ -66,16 +49,9 @@ public interface SingularAttributeBinding extends AttributeBinding {
public boolean hasDerivedValue();
/**
* Convenience method to determine if all {@link SimpleValueBinding simple value bindings} allow nulls.
* Convenience method to determine if all {@link RelationalValueBinding simple value bindings} allow nulls.
*
* @return {@code true} indicates that all values allow {@code null}; {@code false} indicates one or more do not
*/
public boolean isNullable();
/**
* Obtain the generation strategy for this attribute/value.
*
* @return The generation strategy
*/
public PropertyGeneration getGeneration();
}

View File

@ -59,7 +59,7 @@ public abstract class AbstractConstraint implements Constraint {
return columns;
}
protected int getColumnSpan() {
public int getColumnSpan() {
return columns.size();
}

View File

@ -24,6 +24,7 @@
package org.hibernate.metamodel.spi.relational;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@ -38,7 +39,8 @@ public abstract class AbstractTableSpecification implements TableSpecification {
private final static AtomicInteger tableCounter = new AtomicInteger( 0 );
private final int tableNumber;
private final LinkedHashMap<String, SimpleValue> values = new LinkedHashMap<String, SimpleValue>();
private final List<Value> valueList = new ArrayList<Value>();
private final LinkedHashMap<String, Value> valueMap = new LinkedHashMap<String, Value>();
private final PrimaryKey primaryKey = new PrimaryKey( this );
private final List<ForeignKey> foreignKeys = new ArrayList<ForeignKey>();
@ -53,33 +55,38 @@ public abstract class AbstractTableSpecification implements TableSpecification {
}
@Override
public Iterable<SimpleValue> values() {
return values.values();
public List<Value> values() {
return Collections.unmodifiableList( valueList );
}
@Override
public Column locateOrCreateColumn(String name) {
if ( values.containsKey( name ) ) {
return (Column) values.get( name );
if ( valueMap.containsKey( name ) ) {
return (Column) valueMap.get( name );
}
final Column column = new Column( this, values.size(), name );
values.put( name, column );
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 ( values.containsKey( fragment ) ) {
return (DerivedValue) values.get( fragment );
public Column locateColumn(String name) {
if ( valueMap.containsKey( name ) ) {
return (Column) valueMap.get( name );
}
final DerivedValue value = new DerivedValue( this, values.size(), fragment );
values.put( fragment, value );
return value;
return null;
}
@Override
public Tuple createTuple(String name) {
return new Tuple( this, name );
public DerivedValue locateOrCreateDerivedValue(String fragment) {
if ( valueMap.containsKey( fragment ) ) {
return (DerivedValue) valueMap.get( fragment );
}
final DerivedValue value = new DerivedValue( this, valueList.size(), fragment );
valueMap.put( fragment, value );
valueList.add( value );
return value;
}
@Override

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
* 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
@ -29,19 +29,19 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.ValidationException;
/**
* Basic support for {@link SimpleValue} implementations.
* Basic support for {@link Value} implementations.
*
* @author Steve Ebersole
*/
public abstract class AbstractSimpleValue implements SimpleValue {
public abstract class AbstractValue implements Value {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AbstractSimpleValue.class.getName());
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AbstractValue.class.getName());
private final TableSpecification table;
private final int position;
private Datatype datatype;
private JdbcDataType jdbcDataType;
protected AbstractSimpleValue(TableSpecification table, int position) {
protected AbstractValue(TableSpecification table, int position) {
this.table = table;
this.position = position;
}
@ -56,23 +56,22 @@ public abstract class AbstractSimpleValue implements SimpleValue {
}
@Override
public Datatype getDatatype() {
return datatype;
public JdbcDataType getJdbcDataType() {
return jdbcDataType;
}
@Override
public void setDatatype(Datatype datatype) {
LOG.debugf( "setting datatype for column %s : %s", toLoggableString(), datatype );
if ( this.datatype != null && ! this.datatype.equals( datatype ) ) {
LOG.debugf( "overriding previous datatype : %s", this.datatype );
public void setJdbcDataType(JdbcDataType jdbcDataType) {
LOG.debugf( "setting jdbcDataType for column %s : %s", toLoggableString(), jdbcDataType );
if ( this.jdbcDataType != null && ! this.jdbcDataType.equals( jdbcDataType ) ) {
LOG.debugf( "overriding previous jdbcDataType : %s", this.jdbcDataType );
}
this.datatype = datatype;
this.jdbcDataType = jdbcDataType;
}
@Override
public void validateJdbcTypes(JdbcCodes typeCodes) {
// todo : better compatibility testing...
if ( datatype.getTypeCode() != typeCodes.nextJdbcCde() ) {
if ( jdbcDataType.getTypeCode() != typeCodes.nextJdbcCde() ) {
throw new ValidationException( "Mismatched types" );
}
}

View File

@ -34,7 +34,7 @@ import org.hibernate.metamodel.spi.relational.state.ColumnRelationalState;
* @author Gavin King
* @author Steve Ebersole
*/
public class Column extends AbstractSimpleValue {
public class Column extends AbstractValue {
private final Identifier columnName;
private boolean nullable;
private boolean unique;

View File

@ -30,7 +30,7 @@ import org.hibernate.dialect.Dialect;
*
* @author Steve Ebersole
*/
public class DerivedValue extends AbstractSimpleValue {
public class DerivedValue extends AbstractValue {
private final String expression;
public DerivedValue(TableSpecification table, int position, String expression) {

View File

@ -24,26 +24,34 @@
package org.hibernate.metamodel.spi.relational;
/**
* Models a JDBC {@link java.sql.Types DATATYPE}
* Models a JDBC {@link java.sql.Types DATATYPE}. Mainly breaks down into 3 pieces of information:<ul>
* <li>
* {@link #getTypeCode() type code} - The JDBC type code; generally matches a code from {@link java.sql.Types}
* though not necessarily.
* </li>
* <li>
* {@link #getTypeName() type name} - The database type name for the given type code.
* </li>
* <li>
* {@link #getJavaType()} java type} - The java type recommended for representing this JDBC type (if known)
* </li>
* </ul>
*
* @todo Do we somehow link this in with {@link org.hibernate.internal.util.jdbc.TypeInfo} ?
* @todo Would love to link this in with {@link org.hibernate.engine.jdbc.internal.TypeInfo}
*
* @author Steve Ebersole
*/
public class Datatype {
public class JdbcDataType {
private final int typeCode;
private final String typeName;
private final Class javaType;
private final int hashCode;
public Datatype(int typeCode, String typeName, Class javaType) {
public JdbcDataType(int typeCode, String typeName, Class javaType) {
this.typeCode = typeCode;
this.typeName = typeName;
this.javaType = javaType;
this.hashCode = generateHashCode();
}
private int generateHashCode() {
int result = typeCode;
if ( typeName != null ) {
result = 31 * result + typeName.hashCode();
@ -51,8 +59,8 @@ public class Datatype {
if ( javaType != null ) {
result = 31 * result + javaType.hashCode();
}
return result;
}
this.hashCode = result;
}
public int getTypeCode() {
return typeCode;
@ -66,6 +74,11 @@ public class Datatype {
return javaType;
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
@ -75,19 +88,14 @@ public class Datatype {
return false;
}
Datatype datatype = (Datatype) o;
JdbcDataType jdbcDataType = (JdbcDataType) o;
return typeCode == datatype.typeCode
&& javaType.equals( datatype.javaType )
&& typeName.equals( datatype.typeName );
return typeCode == jdbcDataType.typeCode
&& javaType.equals( jdbcDataType.javaType )
&& typeName.equals( jdbcDataType.typeName );
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public String toString() {
return super.toString() + "[code=" + typeCode + ", name=" + typeName + ", javaClass=" + javaType.getName() + "]";

View File

@ -1,58 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @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.relational;
import org.hibernate.dialect.Dialect;
/**
* Models a simple, non-compound value.
*
* @author Steve Ebersole
*/
public interface SimpleValue extends Value {
/**
* Retrieve the datatype of this value.
*
* @return The value's datatype
*/
public Datatype getDatatype();
/**
* Set the datatype of this value.
*
* @param datatype The value's datatype
*/
public void setDatatype(Datatype datatype);
/**
* For any column name, generate an alias that is unique
* to that column name, unique across tables, and within
* alias size constraints determined by
* {@link org.hibernate.dialect.Dialect#getMaxAliasLength()}.
*
* @param dialect the dialect.
* @return the alias.
*/
public String getAlias(Dialect dialect);
}

View File

@ -162,7 +162,7 @@ public class Table extends AbstractTableSpecification implements Exportable {
}
boolean isFirst = true;
for ( SimpleValue simpleValue : values() ) {
for ( Value simpleValue : values() ) {
if ( ! Column.class.isInstance( simpleValue ) ) {
continue;
}
@ -183,7 +183,7 @@ public class Table extends AbstractTableSpecification implements Exportable {
buf.append( getTypeString( col, dialect ) );
}
buf.append( ' ' )
.append( dialect.getIdentityColumnString( col.getDatatype().getTypeCode() ) );
.append( dialect.getIdentityColumnString( col.getJdbcDataType().getTypeCode() ) );
}
else {
buf.append( getTypeString( col, dialect ) );
@ -271,7 +271,7 @@ public class Table extends AbstractTableSpecification implements Exportable {
col.getSize();
typeString = dialect.getTypeName(
col.getDatatype().getTypeCode(),
col.getJdbcDataType().getTypeCode(),
size.getLength(),
size.getPrecision(),
size.getScale()

View File

@ -62,13 +62,13 @@ public interface TableSpecification extends ValueContainer, Loggable {
public Column locateOrCreateColumn(String name);
/**
* Factory method for creating a {@link Column} associated with this container.
* Attempt to locate a column with the given name
*
* @param name The column name
*
* @return The generated column
* @return The located column, or {@code null} is none found
*/
public Tuple createTuple(String name);
public Column locateColumn(String name);
/**
* Factory method for creating a {@link DerivedValue} associated with this container.

View File

@ -1,91 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @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.relational;
import java.util.LinkedHashSet;
/**
* Models a compound value (a tuple or row-value-constructor is SQL terms). It is both a {@link Value} and
* a {@link ValueContainer} simultaneously.
* <p/>
* IMPL NOTE : in terms of the tables themselves, SQL has no notion of a tuple/compound-value. We simply model
* it this way because:
* <ul>
* <li>it is a cleaner mapping to the logical model</li>
* <li>it allows more meaningful traversals from simple values back up to table through any intermediate tuples
* because it gives us a better understanding of the model.</li>
* <li>it better conveys intent</li>
* <li>it adds richness to the model</li>
* </ul>
*
* @author Steve Ebersole
*/
public class Tuple implements Value, ValueContainer, Loggable {
private final TableSpecification table;
private final String name;
private final LinkedHashSet<SimpleValue> values = new LinkedHashSet<SimpleValue>();
public Tuple(TableSpecification table, String name) {
this.table = table;
this.name = name;
}
@Override
public TableSpecification getTable() {
return table;
}
public int valuesSpan() {
return values.size();
}
@Override
public Iterable<SimpleValue> values() {
return values;
}
public void addValue(SimpleValue value) {
if ( ! value.getTable().equals( getTable() ) ) {
throw new IllegalArgumentException( "Tuple can only group values from same table" );
}
values.add( value );
}
@Override
public String getLoggableValueQualifier() {
return getTable().getLoggableValueQualifier() + '.' + name + "{tuple}";
}
@Override
public String toLoggableString() {
return getLoggableValueQualifier();
}
@Override
public void validateJdbcTypes(JdbcCodes typeCodes) {
for ( Value value : values() ) {
value.validateJdbcTypes( typeCodes );
}
}
}

View File

@ -23,9 +23,11 @@
*/
package org.hibernate.metamodel.spi.relational;
import org.hibernate.dialect.Dialect;
/**
* Models a value within a {@link ValueContainer}. This will generally be either a {@link Column column} or a
* {@link DerivedValue derived value}, but we also allow the notion of {@link Tuple} at this level
* Models a value within a {@link ValueContainer}. Concretely, either a {@link Column column} or a
* {@link DerivedValue derived value}.
*
* @author Steve Ebersole
*/
@ -37,6 +39,13 @@ public interface Value {
*/
public TableSpecification getTable();
/**
* Retrieve the JDBC data type of this value.
*
* @return The value's JDBC data type
*/
public JdbcDataType getJdbcDataType();
/**
* Obtain the string representation of this value usable in log statements.
*
@ -44,6 +53,29 @@ public interface Value {
*/
public String toLoggableString();
/**
* For any column name, generate an alias that is unique
* to that column name, unique across tables, and within
* alias size constraints determined by
* {@link org.hibernate.dialect.Dialect#getMaxAliasLength()}.
*
* todo : not sure this contract is the best place for this method
*
* @param dialect the dialect.
* @return the alias.
*/
public String getAlias(Dialect dialect);
/**
* Validate the value against the incoming JDBC type code array, both in terms of number of types
* and compatibility of types.
*
* @param typeCodes The type codes.
*
* @throws org.hibernate.metamodel.ValidationException if validaton fails.
*/
public void validateJdbcTypes(JdbcCodes typeCodes);
/**
* Used to track JDBC type usage throughout a series of potential recursive calls to component
* values since we do not know ahead of time which values correspond to which indexes of the
@ -66,14 +98,4 @@ public interface Value {
}
}
/**
* Validate the value against the incoming JDBC type code array, both in terms of number of types
* and compatibility of types.
*
* @param typeCodes The type codes.
*
* @throws org.hibernate.metamodel.ValidationException if validaton fails.
*/
public void validateJdbcTypes(JdbcCodes typeCodes);
}

View File

@ -23,20 +23,23 @@
*/
package org.hibernate.metamodel.spi.relational;
import java.util.List;
/**
* Contract for data containers (what the ANSI SQL spec calls "table specifications") to which we can map
* entity state. The two flavors here are {@link Table physical table} and {@link InLineView inline view}, but a
* {@link Tuple} is a conceptual value container as well.
* entity state. The two flavors here are {@link Table physical table} and {@link InLineView inline view}.
*
* @author Steve Ebersole
*/
public interface ValueContainer {
/**
* Obtain an iterator over this containers current set of value definitions.
* <p/>
* The returned list is unmodifiable!
*
* @return Iterator over value definitions.
*/
public Iterable<SimpleValue> values();
public List<Value> values();
/**
* Get a qualifier which can be used to qualify {@link Value values} belonging to this container in

View File

@ -24,7 +24,7 @@
package org.hibernate.metamodel.spi.source;
import org.hibernate.TruthValue;
import org.hibernate.metamodel.spi.relational.Datatype;
import org.hibernate.metamodel.spi.relational.JdbcDataType;
import org.hibernate.metamodel.spi.relational.Size;
/**
@ -85,7 +85,7 @@ public interface ColumnSource extends RelationalValueSource {
*
* @return The column's SQL data type.
*/
public Datatype getDatatype();
public JdbcDataType getDatatype();
/**
* Obtain the specified column size.

View File

@ -50,7 +50,7 @@ public interface RootEntitySource extends EntitySource {
*
* @return the source information about the attribute used for versioning
*/
public SingularAttributeSource getVersioningAttributeSource();
public VersionAttributeSource getVersioningAttributeSource();
/**
* Obtain the source information about the discriminator attribute for single table inheritance

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.spi.source;
import org.hibernate.TruthValue;
import org.hibernate.mapping.PropertyGeneration;
/**

View File

@ -45,4 +45,11 @@ public interface ToOneAttributeSource
* @return The name of the referenced attribute; {@code null} indicates the identifier attribute.
*/
public String getReferencedEntityAttributeName();
/**
* Retrieve the name of the foreign key as supplied by the user, or {@code null} if the user supplied none.
*
* @return The user supplied foreign key name.
*/
public String getForeignKeyName();
}

View File

@ -0,0 +1,31 @@
/*
* 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.source;
/**
* @author Steve Ebersole
*/
public interface VersionAttributeSource extends SingularAttributeSource {
public String getUnsavedValue();
}

View File

@ -96,8 +96,9 @@ import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.SimpleValueBinding;
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.metamodel.spi.relational.DerivedValue;
@ -795,7 +796,11 @@ public abstract class AbstractEntityPersister
// IDENTIFIER
identifierColumnSpan = entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding().getSimpleValueSpan();
identifierColumnSpan = entityBinding.getHierarchyDetails()
.getEntityIdentifier()
.getValueBinding()
.getRelationalValueBindings()
.size();
rootTableKeyColumnNames = new String[identifierColumnSpan];
rootTableKeyColumnReaders = new String[identifierColumnSpan];
rootTableKeyColumnReaderTemplates = new String[identifierColumnSpan];
@ -823,9 +828,20 @@ public abstract class AbstractEntityPersister
// VERSION
if ( entityBinding.isVersioned() ) {
final Value versioningValue = entityBinding.getHierarchyDetails().getVersioningAttributeBinding().getValue();
final BasicAttributeBinding versionAttributeBinding = entityBinding.getHierarchyDetails()
.getEntityVersion()
.getVersioningAttributeBinding();
if ( versionAttributeBinding.getRelationalValueBindings().size() > 1 ) {
throw new AssertionFailure(
"Bad versioning attribute binding, expecting single column but found " +
versionAttributeBinding.getRelationalValueBindings().size()
);
}
final Value versioningValue = versionAttributeBinding.getRelationalValueBindings().get( 0 ).getValue();
if ( ! org.hibernate.metamodel.spi.relational.Column.class.isInstance( versioningValue ) ) {
throw new AssertionFailure( "Bad versioning attribute binding : " + versioningValue );
throw new AssertionFailure(
"Bad versioning attribute binding, expecting column but found [" + versioningValue + "]"
);
}
org.hibernate.metamodel.spi.relational.Column versionColumn = org.hibernate.metamodel.spi.relational.Column.class.cast( versioningValue );
versionColumnName = versionColumn.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() );
@ -882,7 +898,7 @@ public abstract class AbstractEntityPersister
propertySubclassNames[i] = ( (EntityBinding) singularAttributeBinding.getContainer() ).getEntity().getName();
int span = singularAttributeBinding.getSimpleValueSpan();
int span = singularAttributeBinding.getRelationalValueBindings().size();
propertyColumnSpans[i] = span;
String[] colNames = new String[span];
@ -895,14 +911,14 @@ public abstract class AbstractEntityPersister
int k = 0;
for ( SimpleValueBinding valueBinding : singularAttributeBinding.getSimpleValueBindings() ) {
colAliases[k] = valueBinding.getSimpleValue().getAlias( factory.getDialect() );
for ( RelationalValueBinding valueBinding : singularAttributeBinding.getRelationalValueBindings() ) {
colAliases[k] = valueBinding.getValue().getAlias( factory.getDialect() );
if ( valueBinding.isDerived() ) {
foundFormula = true;
formulaTemplates[ k ] = getTemplateFromString( ( (DerivedValue) valueBinding.getSimpleValue() ).getExpression(), factory );
formulaTemplates[ k ] = getTemplateFromString( ( (DerivedValue) valueBinding.getValue() ).getExpression(), factory );
}
else {
org.hibernate.metamodel.spi.relational.Column col = (org.hibernate.metamodel.spi.relational.Column) valueBinding.getSimpleValue();
org.hibernate.metamodel.spi.relational.Column col = (org.hibernate.metamodel.spi.relational.Column) valueBinding.getValue();
colNames[k] = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() );
colReaderTemplates[k] = getTemplateFromColumn( col, factory );
colWriters[k] = col.getWriteFragment() == null ? "?" : col.getWriteFragment();
@ -989,7 +1005,7 @@ public abstract class AbstractEntityPersister
propNullables.add( singularAttributeBinding.isNullable() || isDefinedBySubclass ); //TODO: is this completely correct?
types.add( singularAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
final int span = singularAttributeBinding.getSimpleValueSpan();
final int span = singularAttributeBinding.getRelationalValueBindings().size();
String[] cols = new String[ span ];
String[] readers = new String[ span ];
String[] readerTemplates = new String[ span ];
@ -998,9 +1014,9 @@ public abstract class AbstractEntityPersister
int[] formnos = new int[ span ];
int l = 0;
Boolean lazy = singularAttributeBinding.isLazy() && lazyAvailable;
for ( SimpleValueBinding valueBinding : singularAttributeBinding.getSimpleValueBindings() ) {
for ( RelationalValueBinding valueBinding : singularAttributeBinding.getRelationalValueBindings() ) {
if ( valueBinding.isDerived() ) {
DerivedValue derivedValue = DerivedValue.class.cast( valueBinding.getSimpleValue() );
DerivedValue derivedValue = DerivedValue.class.cast( valueBinding.getValue() );
String template = getTemplateFromString( derivedValue.getExpression(), factory );
formnos[l] = formulaTemplates.size();
colnos[l] = -1;
@ -1011,7 +1027,7 @@ public abstract class AbstractEntityPersister
formulasLazy.add( lazy );
}
else {
org.hibernate.metamodel.spi.relational.Column col = org.hibernate.metamodel.spi.relational.Column.class.cast( valueBinding.getSimpleValue() );
org.hibernate.metamodel.spi.relational.Column col = org.hibernate.metamodel.spi.relational.Column.class.cast( valueBinding.getValue() );
String colName = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() );
colnos[l] = columns.size(); //before add :-)
formnos[l] = -1;

View File

@ -50,10 +50,9 @@ import org.hibernate.mapping.Value;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.CustomSQL;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.SimpleValueBinding;
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.metamodel.spi.relational.DerivedValue;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.sql.InFragment;
import org.hibernate.sql.Insert;
@ -537,7 +536,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
// DISCRIMINATOR
if ( entityBinding.isPolymorphic() ) {
SimpleValue discriminatorRelationalValue = entityBinding.getHierarchyDetails().getEntityDiscriminator().getBoundValue();
org.hibernate.metamodel.spi.relational.Value discriminatorRelationalValue = entityBinding.getHierarchyDetails().getEntityDiscriminator().getRelationalValue();
if ( discriminatorRelationalValue == null ) {
throw new MappingException("discriminator mapping required for single table polymorphic persistence");
}
@ -652,8 +651,8 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
join
);
for ( SimpleValueBinding simpleValueBinding : singularAttributeBinding.getSimpleValueBindings() ) {
if ( DerivedValue.class.isInstance( simpleValueBinding.getSimpleValue() ) ) {
for ( RelationalValueBinding relationalValueBinding : singularAttributeBinding.getRelationalValueBindings() ) {
if ( DerivedValue.class.isInstance( relationalValueBinding.getValue() ) ) {
formulaJoinedNumbers.add( join );
}
else {

View File

@ -203,7 +203,7 @@ public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegi
PluralAttributeBinding collectionMetadata,
CollectionRegionAccessStrategy cacheAccessStrategy,
SessionFactoryImplementor factory) throws HibernateException {
Class<? extends CollectionPersister> persisterClass = collectionMetadata.getCollectionPersisterClass();
Class<? extends CollectionPersister> persisterClass = collectionMetadata.getExplicitPersisterClass();
if ( persisterClass == null ) {
persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( collectionMetadata );
}

View File

@ -42,7 +42,7 @@ import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeAssociationElementBinding;
import org.hibernate.metamodel.spi.binding.SimpleValueBinding;
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.property.Getter;
@ -117,7 +117,7 @@ public class PropertyFactory {
// (steve) virtual attributes will still be attributes, they will simply be marked as virtual.
// see org.hibernate.metamodel.domain.AbstractAttributeContainer.locateOrCreateVirtualAttribute()
final String mappedUnsavedValue = property.getUnsavedValue();
final String mappedUnsavedValue = mappedEntity.getHierarchyDetails().getEntityIdentifier().getUnsavedValue();
final Type type = property.getHibernateTypeDescriptor().getResolvedTypeMapping();
IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue(
@ -194,10 +194,12 @@ public class PropertyFactory {
* @param lazyAvailable Is property lazy loading currently available.
* @return The appropriate VersionProperty definition.
*/
public static VersionProperty buildVersionProperty(BasicAttributeBinding property, boolean lazyAvailable) {
String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
public static VersionProperty buildVersionProperty(
EntityBinding entityBinding,
BasicAttributeBinding property,
boolean lazyAvailable) {
final String mappedUnsavedValue = entityBinding.getHierarchyDetails().getEntityVersion().getUnsavedValue();
final VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
mappedUnsavedValue,
getGetter( property ),
(VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
@ -297,6 +299,9 @@ public class PropertyFactory {
? ( (SingularAssociationAttributeBinding) singularAttributeBinding ).getFetchMode()
: FetchMode.DEFAULT;
PropertyGeneration propertyGeneration = BasicAttributeBinding.class.isInstance( property )
? ( (BasicAttributeBinding) property ).getGeneration()
: PropertyGeneration.NEVER;
return new StandardProperty(
singularAttributeBinding.getAttribute().getName(),
null,
@ -304,9 +309,9 @@ public class PropertyFactory {
lazyAvailable && singularAttributeBinding.isLazy(),
true, // insertable
true, // updatable
singularAttributeBinding.getGeneration() == PropertyGeneration.INSERT
|| singularAttributeBinding.getGeneration() == PropertyGeneration.ALWAYS,
singularAttributeBinding.getGeneration() == PropertyGeneration.ALWAYS,
propertyGeneration == PropertyGeneration.INSERT
|| propertyGeneration == PropertyGeneration.ALWAYS,
propertyGeneration == PropertyGeneration.ALWAYS,
singularAttributeBinding.isNullable(),
alwaysDirtyCheck || areAllValuesIncludedInUpdate( singularAttributeBinding ),
singularAttributeBinding.isIncludedInOptimisticLocking(),
@ -348,7 +353,7 @@ public class PropertyFactory {
if ( attributeBinding.hasDerivedValue() ) {
return false;
}
for ( SimpleValueBinding valueBinding : attributeBinding.getSimpleValueBindings() ) {
for ( RelationalValueBinding valueBinding : attributeBinding.getRelationalValueBindings() ) {
if ( ! valueBinding.isIncludeInUpdate() ) {
return false;
}

View File

@ -428,10 +428,11 @@ public class EntityMetamodel implements Serializable {
continue;
}
if ( attributeBinding == entityBinding.getHierarchyDetails().getVersioningAttributeBinding() ) {
if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityVersion().getVersioningAttributeBinding() ) {
tempVersionProperty = i;
properties[i] = PropertyFactory.buildVersionProperty(
entityBinding.getHierarchyDetails().getVersioningAttributeBinding(),
entityBinding,
entityBinding.getHierarchyDetails().getEntityVersion().getVersioningAttributeBinding(),
instrumentationMetadata.isInstrumented()
);
}

View File

@ -4,7 +4,7 @@
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Demonstrates use of the TIMESTAMP datatype available in Sybase
Demonstrates use of the TIMESTAMP jdbcDataType available in Sybase
and SQL Server for optimistic locking value.
-->
<hibernate-mapping package="org.hibernate.test.version.sybase">

View File

@ -150,7 +150,7 @@ public class AssertSourcesTest extends BaseUnitTestCase {
// assertNull( columnSource.getSqlType() );
// assertNull( columnSource.getCheckCondition() );
// assertNull( columnSource.getComment() );
// assertNull( columnSource.getDatatype() );
// assertNull( columnSource.getJdbcDataType() );
// assertNull( columnSource.getSize() );
// // todo : technically, pk has to be unique, but this another semantic case
// assertFalse( columnSource.isUnique() );

View File

@ -31,14 +31,14 @@ import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.junit.Test;
import org.hibernate.annotations.Parent;
import org.hibernate.annotations.Target;
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
import org.hibernate.metamodel.spi.binding.ComponentAttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
@ -120,7 +120,9 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
assertNotNull( componentBinding.locateAttributeBinding( "name" ) );
BasicAttributeBinding nameAttribute = (BasicAttributeBinding) componentBinding.locateAttributeBinding( "name" );
org.hibernate.metamodel.spi.relational.Column column = (org.hibernate.metamodel.spi.relational.Column) nameAttribute.getValue();
assertEquals( 1, nameAttribute.getRelationalValueBindings().size() );
org.hibernate.metamodel.spi.relational.Column column
= (org.hibernate.metamodel.spi.relational.Column) nameAttribute.getRelationalValueBindings().get( 0 ).getValue();
assertEquals( "Attribute override specifies a custom column name", "FUBAR", column.getColumnName().getName() );
assertEquals( "Attribute override specifies a custom size", 42, column.getSize().getLength() );
}
@ -178,7 +180,9 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
BasicAttributeBinding stateAttribute = (BasicAttributeBinding) attributeComponentBinding.locateAttributeBinding(
"state"
);
org.hibernate.metamodel.spi.relational.Column column = (org.hibernate.metamodel.spi.relational.Column) stateAttribute.getValue();
assertEquals( 1, stateAttribute.getRelationalValueBindings().size() );
org.hibernate.metamodel.spi.relational.Column column
= (org.hibernate.metamodel.spi.relational.Column) stateAttribute.getRelationalValueBindings().get( 0 ).getValue();
assertEquals(
"Attribute override specifies a custom column name",
"ADDR_STATE",
@ -194,7 +198,8 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
);
BasicAttributeBinding nameAttribute = (BasicAttributeBinding) zipComponentBinding.locateAttributeBinding( "zip" );
column = (org.hibernate.metamodel.spi.relational.Column) nameAttribute.getValue();
assertEquals( 1, nameAttribute.getRelationalValueBindings().size() );
column = (org.hibernate.metamodel.spi.relational.Column) nameAttribute.getRelationalValueBindings().get( 0 ).getValue();
assertEquals(
"Attribute override specifies a custom column name",
"ADDR_ZIP",
@ -270,7 +275,9 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
);
BasicAttributeBinding attribute = (BasicAttributeBinding) bComponentBinding.locateAttributeBinding( "foo" );
org.hibernate.metamodel.spi.relational.Column column = (org.hibernate.metamodel.spi.relational.Column) attribute.getValue();
assertEquals( 1, attribute.getRelationalValueBindings().size() );
org.hibernate.metamodel.spi.relational.Column column
= (org.hibernate.metamodel.spi.relational.Column) attribute.getRelationalValueBindings().get( 0 ).getValue();
assertEquals(
"Attribute override specifies a custom column name",
"BAR",
@ -278,7 +285,8 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
);
attribute = (BasicAttributeBinding) bComponentBinding.locateAttributeBinding( "fubar" );
column = (org.hibernate.metamodel.spi.relational.Column) attribute.getValue();
assertEquals( 1, attribute.getRelationalValueBindings().size() );
column = (org.hibernate.metamodel.spi.relational.Column) attribute.getRelationalValueBindings().get( 0 ).getValue();
assertEquals(
"Attribute override specifies a custom column name",
"C_WINS",

View File

@ -41,7 +41,7 @@ import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.EntityDiscriminator;
import org.hibernate.metamodel.spi.relational.DerivedValue;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.Value;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@ -454,7 +454,7 @@ public class InheritanceBindingTest extends BaseAnnotationBindingTestCase {
EntityBinding entityBinding = getEntityBinding( Apple.class );
assertFalse( entityBinding.isRoot() );
EntityDiscriminator discriminator = rootEntityBinding.getHierarchyDetails().getEntityDiscriminator();
SimpleValue simpleValue = discriminator.getBoundValue();
Value simpleValue = discriminator.getRelationalValue();
assertTrue( simpleValue instanceof DerivedValue);
DerivedValue derivedValue = (DerivedValue)simpleValue;
assertEquals( "case when zik_type is null then 0 else zik_type end", derivedValue.getExpression() );

View File

@ -57,7 +57,8 @@ public class MappedSuperclassTest extends BaseAnnotationBindingTestCase {
SingularAttributeBinding nameBinding = (SingularAttributeBinding) binding.locateAttributeBinding( "name" );
assertNotNull( "the name attribute should be bound to MyEntity", nameBinding );
Column column = (Column) nameBinding.getValue();
assertEquals( 1, nameBinding.getRelationalValueBindings().size() );
Column column = (Column) nameBinding.getRelationalValueBindings().get( 0 ).getValue();
assertEquals( "Wrong column name", "MY_NAME", column.getColumnName().toString() );
}
@ -68,7 +69,8 @@ public class MappedSuperclassTest extends BaseAnnotationBindingTestCase {
SingularAttributeBinding fooBinding = (SingularAttributeBinding) binding.locateAttributeBinding( "foo" );
assertNotNull( "the foo attribute should be bound to MyEntity", fooBinding );
Column column = (Column) fooBinding.getValue();
assertEquals( 1, fooBinding.getRelationalValueBindings().size() );
Column column = (Column) fooBinding.getRelationalValueBindings().get( 0 ).getValue();
assertEquals( "Wrong column name", "MY_FOO", column.getColumnName().toString() );
}

View File

@ -23,21 +23,18 @@
*/
package org.hibernate.metamodel.internal.source.annotations.entity;
import java.util.Iterator;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.SecondaryTable;
import org.junit.Test;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.Table;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
@ -47,6 +44,7 @@ import static junit.framework.Assert.fail;
public class SecondaryTableTest extends BaseAnnotationBindingTestCase {
@Entity
@SecondaryTable(name = "SECOND_TABLE")
@SuppressWarnings( {"UnusedDeclaration"})
class EntityWithSecondaryTable {
@Id
private long id;
@ -62,11 +60,9 @@ public class SecondaryTableTest extends BaseAnnotationBindingTestCase {
Table table = (Table) binding.locateTable( "SECOND_TABLE" );
assertEquals( "The secondary table should exist", "SECOND_TABLE", table.getTableName().getName() );
Iterator<SimpleValue> valueIterator = table.values().iterator();
assertTrue( valueIterator.hasNext() );
org.hibernate.metamodel.spi.relational.Column column = (org.hibernate.metamodel.spi.relational.Column) valueIterator.next();
assertEquals( 1, table.values().size() );
org.hibernate.metamodel.spi.relational.Column column = (org.hibernate.metamodel.spi.relational.Column) table.values().get( 0 );
assertEquals( "Wrong column name", "name", column.getColumnName().getName() );
assertFalse( valueIterator.hasNext() );
}
@Test

View File

@ -96,6 +96,7 @@ public class VersionBindingTests extends BaseAnnotationBindingTestCase {
EntityBinding binding = getEntityBinding( Item2.class );
assertTrue( binding.isVersioned() );
HibernateTypeDescriptor descriptor = binding.getHierarchyDetails()
.getEntityVersion()
.getVersioningAttributeBinding()
.getHibernateTypeDescriptor();
// assertEquals( "Long", descriptor.getExplicitTypeName() );
@ -121,6 +122,7 @@ public class VersionBindingTests extends BaseAnnotationBindingTestCase {
EntityBinding binding = getEntityBinding( Item3.class );
assertTrue( binding.isVersioned() );
HibernateTypeDescriptor descriptor = binding.getHierarchyDetails()
.getEntityVersion()
.getVersioningAttributeBinding()
.getHibernateTypeDescriptor();
assertEquals( "dbtimestamp", descriptor.getExplicitTypeName() );

View File

@ -28,6 +28,7 @@ import java.util.Iterator;
import java.util.Set;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -36,8 +37,8 @@ import org.hibernate.metamodel.spi.domain.BasicType;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.internal.MetadataImpl;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.Datatype;
import org.hibernate.metamodel.spi.relational.SimpleValue;
import org.hibernate.metamodel.spi.relational.JdbcDataType;
import org.hibernate.metamodel.spi.relational.Value;
import org.hibernate.metamodel.spi.source.MetadataImplementor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
@ -85,7 +86,7 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
assertRoot( metadata, entityBinding );
assertIdAndSimpleProperty( entityBinding );
assertNull( entityBinding.getHierarchyDetails().getVersioningAttributeBinding() );
assertNull( entityBinding.getHierarchyDetails().getEntityVersion().getVersioningAttributeBinding() );
}
@Test
@ -96,8 +97,8 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
EntityBinding entityBinding = metadata.getEntityBinding( SimpleVersionedEntity.class.getName() );
assertIdAndSimpleProperty( entityBinding );
assertNotNull( entityBinding.getHierarchyDetails().getVersioningAttributeBinding() );
assertNotNull( entityBinding.getHierarchyDetails().getVersioningAttributeBinding().getAttribute() );
assertNotNull( entityBinding.getHierarchyDetails().getEntityVersion().getVersioningAttributeBinding() );
assertNotNull( entityBinding.getHierarchyDetails().getEntityVersion().getVersioningAttributeBinding().getAttribute() );
}
@Test
@ -170,9 +171,10 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
BasicType basicIdAttributeType = ( BasicType ) singularIdAttribute.getSingularAttributeType();
assertSame( Long.class, basicIdAttributeType.getClassReference() );
assertNotNull( singularIdAttributeBinding.getValue() );
assertTrue( singularIdAttributeBinding.getValue() instanceof Column );
Datatype idDataType = ( (Column) singularIdAttributeBinding.getValue() ).getDatatype();
assertTrue( singularIdAttributeBinding.getRelationalValueBindings().size() == 1 );
Value value = singularIdAttributeBinding.getRelationalValueBindings().get( 0 ).getValue();
assertTrue( value instanceof Column );
JdbcDataType idDataType = value.getJdbcDataType();
assertSame( Long.class, idDataType.getJavaType() );
assertSame( Types.BIGINT, idDataType.getTypeCode() );
assertSame( LongType.INSTANCE.getName(), idDataType.getTypeName() );
@ -185,15 +187,14 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
assertTrue( nameBinding.isNullable() );
assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
assertNotNull( nameBinding.getAttribute() );
assertNotNull( nameBinding.getValue() );
SingularAttribute singularNameAttribute = (SingularAttribute) nameBinding.getAttribute();
assertNotNull( nameBinding.getRelationalValueBindings().size() );
SingularAttribute singularNameAttribute = nameBinding.getAttribute();
BasicType basicNameAttributeType = (BasicType) singularNameAttribute.getSingularAttributeType();
assertSame( String.class, basicNameAttributeType.getClassReference() );
assertNotNull( nameBinding.getValue() );
SimpleValue nameValue = (SimpleValue) nameBinding.getValue();
Assert.assertEquals( 1, nameBinding.getRelationalValueBindings().size() );
Value nameValue = (Value) nameBinding.getRelationalValueBindings().get( 0 ).getValue();
assertTrue( nameValue instanceof Column );
Datatype nameDataType = nameValue.getDatatype();
JdbcDataType nameDataType = nameValue.getJdbcDataType();
assertSame( String.class, nameDataType.getJavaType() );
assertSame( Types.VARCHAR, nameDataType.getTypeCode() );
assertSame( StringType.INSTANCE.getName(), nameDataType.getTypeName() );

View File

@ -24,15 +24,18 @@
package org.hibernate.metamodel.spi.binding;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.hibernate.EntityMode;
import org.hibernate.internal.util.Value;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.domain.Entity;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.Datatype;
import org.hibernate.metamodel.spi.relational.JdbcDataType;
import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.metamodel.spi.relational.Size;
import org.hibernate.metamodel.spi.relational.Table;
@ -47,30 +50,46 @@ import static org.junit.Assert.assertSame;
* @author Steve Ebersole
*/
public class SimpleValueBindingTests extends BaseUnitTestCase {
public static final Datatype BIGINT = new Datatype( Types.BIGINT, "BIGINT", Long.class );
public static final Datatype VARCHAR = new Datatype( Types.VARCHAR, "VARCHAR", String.class );
public static final JdbcDataType BIGINT = new JdbcDataType( Types.BIGINT, "BIGINT", Long.class );
public static final JdbcDataType VARCHAR = new JdbcDataType( Types.VARCHAR, "VARCHAR", String.class );
@Test
public void testBasicMiddleOutBuilding() {
Table table = new Table( new Schema( null, null ), "the_table" );
Column idColumn = table.locateOrCreateColumn( "id" );
idColumn.setJdbcDataType( BIGINT );
idColumn.setSize( Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );
table.getPrimaryKey().setName( "my_table_pk" );
Entity entity = new Entity( "TheEntity", "NoSuchClass", makeJavaType( "NoSuchClass" ), null );
EntityBinding entityBinding = new EntityBinding( InheritanceType.NO_INHERITANCE, EntityMode.POJO );
entityBinding.setEntity( entity );
entityBinding.setPrimaryTable( table );
List<RelationalValueBinding> valueBindings = new ArrayList<RelationalValueBinding>();
valueBindings.add(
new RelationalValueBinding(
idColumn,
true,
true
)
);
SingularAttribute idAttribute = entity.createSingularAttribute( "id" );
BasicAttributeBinding attributeBinding = entityBinding.makeBasicAttributeBinding( idAttribute );
BasicAttributeBinding attributeBinding = entityBinding.makeBasicAttributeBinding(
idAttribute,
valueBindings,
"property",
true,
false,
null,
PropertyGeneration.NEVER
);
attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( "long" );
assertSame( idAttribute, attributeBinding.getAttribute() );
entityBinding.getHierarchyDetails().getEntityIdentifier().setValueBinding( attributeBinding );
Column idColumn = table.locateOrCreateColumn( "id" );
idColumn.setDatatype( BIGINT );
idColumn.setSize( Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );
table.getPrimaryKey().setName( "my_table_pk" );
//attributeBinding.setValue( idColumn );
}

View File

@ -41,8 +41,8 @@ import static org.junit.Assert.assertTrue;
* @author Steve Ebersole
*/
public class TableManipulationTests extends BaseUnitTestCase {
public static final Datatype VARCHAR = new Datatype( Types.VARCHAR, "VARCHAR", String.class );
public static final Datatype INTEGER = new Datatype( Types.INTEGER, "INTEGER", Long.class );
public static final JdbcDataType VARCHAR = new JdbcDataType( Types.VARCHAR, "VARCHAR", String.class );
public static final JdbcDataType INTEGER = new JdbcDataType( Types.INTEGER, "INTEGER", Long.class );
@Test
public void testTableCreation() {
@ -56,7 +56,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
assertFalse( table.values().iterator().hasNext() );
Column idColumn = table.locateOrCreateColumn( "id" );
idColumn.setDatatype( INTEGER );
idColumn.setJdbcDataType( INTEGER );
idColumn.setSize( Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );
table.getPrimaryKey().setName( "my_table_pk" );
@ -64,14 +64,14 @@ public class TableManipulationTests extends BaseUnitTestCase {
assertEquals( "my_table.PK", table.getPrimaryKey().getExportIdentifier() );
Column col_1 = table.locateOrCreateColumn( "col_1" );
col_1.setDatatype( VARCHAR );
col_1.setJdbcDataType( VARCHAR );
col_1.setSize( Size.length( 512 ) );
for ( Value value : table.values() ) {
assertTrue( Column.class.isInstance( value ) );
Column column = ( Column ) value;
if ( column.getColumnName().getName().equals( "id" ) ) {
assertEquals( INTEGER, column.getDatatype() );
assertEquals( INTEGER, column.getJdbcDataType() );
assertEquals( 18, column.getSize().getPrecision() );
assertEquals( 0, column.getSize().getScale() );
assertEquals( -1, column.getSize().getLength() );
@ -79,7 +79,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
}
else {
assertEquals( "col_1", column.getColumnName().getName() );
assertEquals( VARCHAR, column.getDatatype() );
assertEquals( VARCHAR, column.getJdbcDataType() );
assertEquals( -1, column.getSize().getPrecision() );
assertEquals( -1, column.getSize().getScale() );
assertEquals( 512, column.getSize().getLength() );
@ -109,7 +109,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
Table book = schema.createTable( Identifier.toIdentifier( "BOOK" ) );
Column bookId = book.locateOrCreateColumn( "id" );
bookId.setDatatype( INTEGER );
bookId.setJdbcDataType( INTEGER );
bookId.setSize( Size.precision( 18, 0 ) );
book.getPrimaryKey().addColumn( bookId );
book.getPrimaryKey().setName( "BOOK_PK" );
@ -117,13 +117,13 @@ public class TableManipulationTests extends BaseUnitTestCase {
Table page = schema.createTable( Identifier.toIdentifier( "PAGE" ) );
Column pageId = page.locateOrCreateColumn( "id" );
pageId.setDatatype( INTEGER );
pageId.setJdbcDataType( INTEGER );
pageId.setSize( Size.precision( 18, 0 ) );
page.getPrimaryKey().addColumn( pageId );
page.getPrimaryKey().setName( "PAGE_PK" );
Column pageBookId = page.locateOrCreateColumn( "BOOK_ID" );
pageId.setDatatype( INTEGER );
pageId.setJdbcDataType( INTEGER );
pageId.setSize( Size.precision( 18, 0 ) );
ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK" );
pageBookFk.addColumn( pageBookId );