HHH-7893 - Refactoring Binder code
This commit is contained in:
parent
0ddb9b914a
commit
288823d2dd
File diff suppressed because it is too large
Load Diff
|
@ -33,15 +33,20 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
|
import org.hibernate.cfg.NotYetImplementedException;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
import org.hibernate.internal.util.ValueHolder;
|
||||||
import org.hibernate.internal.util.beans.BeanInfoHelper;
|
import org.hibernate.internal.util.beans.BeanInfoHelper;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.metamodel.spi.MetadataImplementor;
|
import org.hibernate.metamodel.spi.MetadataImplementor;
|
||||||
import org.hibernate.metamodel.spi.binding.AttributeBinding;
|
import org.hibernate.metamodel.spi.binding.AttributeBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
|
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
|
||||||
|
import org.hibernate.metamodel.spi.binding.BasicPluralAttributeElementBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
|
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
|
||||||
|
import org.hibernate.metamodel.spi.binding.EntityIdentifier;
|
||||||
import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor;
|
import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor;
|
||||||
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
|
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
|
||||||
|
import org.hibernate.metamodel.spi.binding.PluralAttributeElementBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
|
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
|
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.TypeDefinition;
|
import org.hibernate.metamodel.spi.binding.TypeDefinition;
|
||||||
|
@ -51,62 +56,334 @@ import org.hibernate.metamodel.spi.relational.AbstractValue;
|
||||||
import org.hibernate.metamodel.spi.relational.JdbcDataType;
|
import org.hibernate.metamodel.spi.relational.JdbcDataType;
|
||||||
import org.hibernate.metamodel.spi.relational.Value;
|
import org.hibernate.metamodel.spi.relational.Value;
|
||||||
import org.hibernate.metamodel.spi.source.AttributeSource;
|
import org.hibernate.metamodel.spi.source.AttributeSource;
|
||||||
|
import org.hibernate.metamodel.spi.source.BasicPluralAttributeElementSource;
|
||||||
import org.hibernate.metamodel.spi.source.ComponentAttributeSource;
|
import org.hibernate.metamodel.spi.source.ComponentAttributeSource;
|
||||||
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
|
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
|
||||||
|
import org.hibernate.metamodel.spi.source.PluralAttributeSource;
|
||||||
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
|
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
|
||||||
import org.hibernate.type.ComponentType;
|
import org.hibernate.type.ComponentType;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
import org.hibernate.type.TypeFactory;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate for handling:<ol>
|
* Delegate for handling:<ol>
|
||||||
* <li>
|
* <li>
|
||||||
* binding of Hibernate type information ({@link ExplicitHibernateTypeSource} ->
|
* binding of Hibernate type information ({@link ExplicitHibernateTypeSource} ->
|
||||||
* {@link HibernateTypeDescriptor}
|
* {@link HibernateTypeDescriptor}
|
||||||
* </li>
|
* </li>
|
||||||
* <li>
|
* <li>
|
||||||
* attempt to resolve the actual {@link Type} instance
|
* attempt to resolve the actual {@link Type} instance
|
||||||
* </li>
|
* </li>
|
||||||
* <li>
|
* <li>
|
||||||
* push java type and JDBC type information reported by the {@link Type} instance to relational/
|
* push java type and JDBC type information reported by the {@link Type} instance to relational/
|
||||||
* domain models.
|
* domain models.
|
||||||
* </li>
|
* </li>
|
||||||
* </ol>
|
* </ol>
|
||||||
* <p/>
|
* <p/>
|
||||||
* Methods intended as entry points are:<ul>
|
* Methods intended as entry points are:<ul>
|
||||||
* <li>{@link #bindSingularAttributeTypeInformation}</li>
|
* <li>{@link #bindSingularAttributeTypeInformation}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p/>
|
* <p/>
|
||||||
* Currently the following methods are also required to be non-private because of handling discriminators which
|
* Currently the following methods are also required to be non-private because of handling discriminators which
|
||||||
* are currently not modeled using attributes:<ul>
|
* are currently not modeled using attributes:<ul>
|
||||||
* <li>{@link #bindJdbcDataType(org.hibernate.type.Type, org.hibernate.metamodel.spi.relational.Value)}</li>
|
* <li>{@link #bindJdbcDataType(org.hibernate.type.Type, org.hibernate.metamodel.spi.relational.Value)}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
* @author Brett Meyer
|
* @author Brett Meyer
|
||||||
*/
|
*/
|
||||||
public class HibernateTypeHelper {
|
class HibernateTypeHelper {
|
||||||
private static final Logger log = Logger.getLogger( HibernateTypeHelper.class );
|
private static final Logger log = Logger.getLogger( HibernateTypeHelper.class );
|
||||||
|
|
||||||
|
/* package-protected */
|
||||||
|
static class ReflectedCollectionJavaTypes {
|
||||||
|
private final String collectionTypeName;
|
||||||
|
private final String collectionElementTypeName;
|
||||||
|
private final String collectionIndexTypeName;
|
||||||
|
|
||||||
|
private ReflectedCollectionJavaTypes(
|
||||||
|
Class<?> collectionType,
|
||||||
|
Class<?> collectionElementType,
|
||||||
|
Class<?> collectionIndexType) {
|
||||||
|
this.collectionTypeName = collectionType != null ? collectionType.getName() : null;
|
||||||
|
this.collectionElementTypeName = collectionElementType != null ? collectionElementType.getName() : null;
|
||||||
|
this.collectionIndexTypeName = collectionIndexType != null ? collectionIndexType.getName() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getCollectionElementTypeName() {
|
||||||
|
return collectionElementTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getCollectionIndexTypeName() {
|
||||||
|
return collectionIndexTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getCollectionTypeName() {
|
||||||
|
return collectionTypeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static String defaultCollectionElementJavaTypeName(
|
||||||
|
final ReflectedCollectionJavaTypes reflectedCollectionJavaTypes) {
|
||||||
|
return reflectedCollectionJavaTypes != null ? reflectedCollectionJavaTypes.getCollectionElementTypeName() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String defaultCollectionIndexJavaTypeName(
|
||||||
|
final ReflectedCollectionJavaTypes reflectedCollectionJavaTypes) {
|
||||||
|
return reflectedCollectionJavaTypes != null ? reflectedCollectionJavaTypes.getCollectionIndexTypeName() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String defaultCollectionJavaTypeName(
|
||||||
|
final ReflectedCollectionJavaTypes reflectedCollectionJavaTypes,
|
||||||
|
final PluralAttributeSource attributeSource) {
|
||||||
|
return reflectedCollectionJavaTypes != null ? reflectedCollectionJavaTypes.getCollectionTypeName() : attributeSource
|
||||||
|
.getNature()
|
||||||
|
.reportedJavaType()
|
||||||
|
.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bindHibernateResolvedType(
|
||||||
|
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
||||||
|
final Type resolvedType) {
|
||||||
|
// Configure relational value JDBC type from Hibernate type descriptor now that its configured
|
||||||
|
if ( resolvedType != null ) {
|
||||||
|
hibernateTypeDescriptor.setResolvedTypeMapping( resolvedType );
|
||||||
|
if ( hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
||||||
|
hibernateTypeDescriptor.setJavaTypeName( resolvedType.getReturnedClass().getName() );
|
||||||
|
}
|
||||||
|
hibernateTypeDescriptor.setToOne( resolvedType.isEntityType() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final Binder binder;
|
private final Binder binder;
|
||||||
private final MetadataImplementor metadata;
|
private final MetadataImplementor metadata;
|
||||||
|
|
||||||
public HibernateTypeHelper( Binder binder,
|
//package scope methods
|
||||||
MetadataImplementor metadata ) {
|
HibernateTypeHelper(Binder binder,
|
||||||
|
MetadataImplementor metadata) {
|
||||||
this.binder = binder;
|
this.binder = binder;
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
private org.hibernate.metamodel.spi.domain.Type makeJavaType(String name) {
|
/**
|
||||||
return binder.bindingContext().makeJavaType( name );
|
* Bind relational types using hibernate type just resolved.
|
||||||
|
*
|
||||||
|
* @param resolvedHibernateType The hibernate type resolved from metadata.
|
||||||
|
* @param value The relational value to be binded.
|
||||||
|
*/
|
||||||
|
void bindJdbcDataType(
|
||||||
|
final Type resolvedHibernateType,
|
||||||
|
final Value value) {
|
||||||
|
if ( value.getJdbcDataType() == null && resolvedHibernateType != null && value != null ) {
|
||||||
|
final Type resolvedRelationalType =
|
||||||
|
resolvedHibernateType.isEntityType()
|
||||||
|
? EntityType.class.cast( resolvedHibernateType ).getIdentifierOrUniqueKeyType( metadata )
|
||||||
|
: resolvedHibernateType;
|
||||||
|
if ( AbstractValue.class.isInstance( value ) ) {
|
||||||
|
( (AbstractValue) value ).setJdbcDataType(
|
||||||
|
new JdbcDataType(
|
||||||
|
resolvedRelationalType.sqlTypes( metadata )[0],
|
||||||
|
resolvedRelationalType.getName(),
|
||||||
|
resolvedRelationalType.getReturnedClass()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindSingularAttributeTypeInformation(
|
void bindJdbcDataType(
|
||||||
SingularAttributeSource attributeSource,
|
final Type resolvedHibernateType,
|
||||||
SingularAttributeBinding attributeBinding) {
|
final List<RelationalValueBinding> relationalValueBindings) {
|
||||||
|
if ( relationalValueBindings.size() <= 1 ) {
|
||||||
|
bindJdbcDataType( resolvedHibernateType, relationalValueBindings.get( 0 ).getValue() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Type resolvedRelationalType =
|
||||||
|
resolvedHibernateType.isEntityType()
|
||||||
|
? EntityType.class.cast( resolvedHibernateType ).getIdentifierOrUniqueKeyType( metadata )
|
||||||
|
: resolvedHibernateType;
|
||||||
|
if ( !CompositeType.class.isInstance( resolvedRelationalType ) ) {
|
||||||
|
throw binder.bindingContext()
|
||||||
|
.makeMappingException( "Column number mismatch" ); // todo refine the exception message
|
||||||
|
}
|
||||||
|
Type[] subTypes = CompositeType.class.cast( resolvedRelationalType ).getSubtypes();
|
||||||
|
for ( int i = 0; i < subTypes.length; i++ ) {
|
||||||
|
bindJdbcDataType( subTypes[i], relationalValueBindings.get( i ).getValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindBasicCollectionElementType(
|
||||||
|
final BasicPluralAttributeElementBinding elementBinding,
|
||||||
|
final BasicPluralAttributeElementSource elementSource,
|
||||||
|
final String defaultElementJavaTypeName) {
|
||||||
|
bindHibernateTypeDescriptor(
|
||||||
|
elementBinding.getHibernateTypeDescriptor(),
|
||||||
|
elementSource.getExplicitHibernateTypeSource(),
|
||||||
|
defaultElementJavaTypeName
|
||||||
|
);
|
||||||
|
Type resolvedElementType = heuristicType( elementBinding.getHibernateTypeDescriptor() );
|
||||||
|
bindHibernateResolvedType( elementBinding.getHibernateTypeDescriptor(), resolvedElementType );
|
||||||
|
bindJdbcDataType(
|
||||||
|
resolvedElementType,
|
||||||
|
elementBinding.getRelationalValueBindings()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type resolvePluralType(
|
||||||
|
final PluralAttributeBinding pluralAttributeBinding,
|
||||||
|
final PluralAttributeSource pluralAttributeSource,
|
||||||
|
final PluralAttributeSource.Nature nature) {
|
||||||
|
if ( pluralAttributeBinding.getHibernateTypeDescriptor().getExplicitTypeName() != null ) {
|
||||||
|
return resolveCustomCollectionType( pluralAttributeBinding );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final TypeFactory typeFactory = metadata.getTypeResolver().getTypeFactory();
|
||||||
|
final String role = pluralAttributeBinding.getAttribute().getRole();
|
||||||
|
final String propertyRef = getReferencedPropertyNameIfNotId( pluralAttributeBinding );
|
||||||
|
final boolean embedded = pluralAttributeBinding.getPluralAttributeElementBinding()
|
||||||
|
.getNature() == PluralAttributeElementBinding.Nature.AGGREGATE;
|
||||||
|
switch ( nature ) {
|
||||||
|
case BAG:
|
||||||
|
return typeFactory.bag( role, propertyRef, embedded );
|
||||||
|
case LIST:
|
||||||
|
return typeFactory.list( role, propertyRef, embedded );
|
||||||
|
case ARRAY:
|
||||||
|
return typeFactory.array(
|
||||||
|
role,
|
||||||
|
propertyRef,
|
||||||
|
embedded,
|
||||||
|
pluralAttributeSource.getElementClassReference().getValue()
|
||||||
|
);
|
||||||
|
case MAP:
|
||||||
|
if ( pluralAttributeBinding.isSorted() ) {
|
||||||
|
return typeFactory.sortedMap(
|
||||||
|
role,
|
||||||
|
propertyRef,
|
||||||
|
embedded,
|
||||||
|
pluralAttributeBinding.getComparator()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// TODO: else if ( pluralAttributeBinding.hasOrder() ) { orderedMap... }
|
||||||
|
else {
|
||||||
|
return typeFactory.map( role, propertyRef, embedded );
|
||||||
|
}
|
||||||
|
case SET:
|
||||||
|
if ( pluralAttributeBinding.isSorted() ) {
|
||||||
|
return typeFactory.sortedSet(
|
||||||
|
role,
|
||||||
|
propertyRef,
|
||||||
|
embedded,
|
||||||
|
pluralAttributeBinding.getComparator()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// TODO: else if ( pluralAttributeBinding.hasOrder() ) { orderedSet... }
|
||||||
|
else {
|
||||||
|
return typeFactory.set( role, propertyRef, embedded );
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new NotYetImplementedException( nature + " is to be implemented" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Type heuristicType(
|
||||||
|
final HibernateTypeDescriptor hibernateTypeDescriptor) {
|
||||||
|
final String typeName =
|
||||||
|
hibernateTypeDescriptor.getExplicitTypeName() != null
|
||||||
|
? hibernateTypeDescriptor.getExplicitTypeName()
|
||||||
|
: hibernateTypeDescriptor.getJavaTypeName();
|
||||||
|
final Properties properties = new Properties();
|
||||||
|
properties.putAll( hibernateTypeDescriptor.getTypeParameters() );
|
||||||
|
return metadata.getTypeResolver().heuristicType( typeName, properties );
|
||||||
|
}
|
||||||
|
// TODO: The following 3 methods should eventually be replaced w/
|
||||||
|
// typeHelper use.
|
||||||
|
|
||||||
|
void bindHibernateTypeDescriptor(
|
||||||
|
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
||||||
|
final ExplicitHibernateTypeSource explicitTypeSource,
|
||||||
|
final ValueHolder<Class<?>> defaultJavaType) {
|
||||||
|
// if there is an explicit type name specified, then there's no reason to
|
||||||
|
// initialize the default Java type name; simply pass a null default instead.
|
||||||
|
bindHibernateTypeDescriptor(
|
||||||
|
hibernateTypeDescriptor,
|
||||||
|
explicitTypeSource,
|
||||||
|
explicitTypeSource == null || explicitTypeSource.getName() == null
|
||||||
|
? defaultJavaType.getValue().getName()
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindHibernateTypeDescriptor(
|
||||||
|
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
||||||
|
final ExplicitHibernateTypeSource explicitTypeSource,
|
||||||
|
final String defaultJavaTypeName) {
|
||||||
|
if ( explicitTypeSource == null ) {
|
||||||
|
bindHibernateTypeDescriptor(
|
||||||
|
hibernateTypeDescriptor, null, null, defaultJavaTypeName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bindHibernateTypeDescriptor(
|
||||||
|
hibernateTypeDescriptor,
|
||||||
|
explicitTypeSource.getName(),
|
||||||
|
explicitTypeSource.getParameters(),
|
||||||
|
defaultJavaTypeName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindHibernateTypeDescriptor(
|
||||||
|
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
||||||
|
final String explicitTypeName,
|
||||||
|
final Map<String, String> explictTypeParameters,
|
||||||
|
final String defaultJavaTypeName) {
|
||||||
|
if ( explicitTypeName == null ) {
|
||||||
|
if ( hibernateTypeDescriptor.getJavaTypeName() != null ) {
|
||||||
|
throw binder.bindingContext().makeMappingException(
|
||||||
|
String.format(
|
||||||
|
"Attempt to re-initialize (non-explicit) Java type name; current=%s new=%s",
|
||||||
|
hibernateTypeDescriptor.getJavaTypeName(),
|
||||||
|
defaultJavaTypeName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
hibernateTypeDescriptor.setJavaTypeName( defaultJavaTypeName );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Check if user-specified name is of a User-Defined Type (UDT)
|
||||||
|
final TypeDefinition typeDef = metadata.getTypeDefinition( explicitTypeName );
|
||||||
|
if ( hibernateTypeDescriptor.getExplicitTypeName() != null ) {
|
||||||
|
throw binder.bindingContext().makeMappingException(
|
||||||
|
String.format(
|
||||||
|
"Attempt to re-initialize explicity-mapped Java type name; current=%s new=%s",
|
||||||
|
hibernateTypeDescriptor.getExplicitTypeName(),
|
||||||
|
explicitTypeName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ( typeDef == null ) {
|
||||||
|
hibernateTypeDescriptor.setExplicitTypeName( explicitTypeName );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hibernateTypeDescriptor.setExplicitTypeName( typeDef.getTypeImplementorClass().getName() );
|
||||||
|
// Don't use set() -- typeDef#parameters is unmodifiable
|
||||||
|
hibernateTypeDescriptor.getTypeParameters().putAll( typeDef.getParameters() );
|
||||||
|
}
|
||||||
|
if ( explictTypeParameters != null ) {
|
||||||
|
hibernateTypeDescriptor.getTypeParameters().putAll( explictTypeParameters );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindSingularAttributeTypeInformation(
|
||||||
|
final SingularAttributeSource attributeSource,
|
||||||
|
final SingularAttributeBinding attributeBinding) {
|
||||||
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding
|
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding
|
||||||
.getHibernateTypeDescriptor();
|
.getHibernateTypeDescriptor();
|
||||||
|
|
||||||
|
@ -117,26 +394,35 @@ public class HibernateTypeHelper {
|
||||||
attributeBinding.getAttribute()
|
attributeBinding.getAttribute()
|
||||||
) : null;
|
) : null;
|
||||||
if ( attributeJavaType != null ) {
|
if ( attributeJavaType != null ) {
|
||||||
attributeBinding.getAttribute().resolveType( makeJavaType(
|
attributeBinding.getAttribute().resolveType(
|
||||||
attributeJavaType.getName() ) );
|
makeJavaType(
|
||||||
|
attributeJavaType.getName()
|
||||||
|
)
|
||||||
|
);
|
||||||
if ( hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
if ( hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
||||||
hibernateTypeDescriptor.setJavaTypeName(
|
hibernateTypeDescriptor.setJavaTypeName(
|
||||||
attributeJavaType.getName() );
|
attributeJavaType.getName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bindHibernateTypeInformation( attributeSource.getTypeInformation(),
|
bindHibernateTypeInformation(
|
||||||
hibernateTypeDescriptor );
|
attributeSource.getTypeInformation(),
|
||||||
|
hibernateTypeDescriptor
|
||||||
|
);
|
||||||
|
|
||||||
processSingularAttributeTypeInformation( attributeSource,
|
processSingularAttributeTypeInformation(
|
||||||
attributeBinding );
|
attributeSource,
|
||||||
|
attributeBinding
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReflectedCollectionJavaTypes getReflectedCollectionJavaTypes(
|
ReflectedCollectionJavaTypes getReflectedCollectionJavaTypes(
|
||||||
PluralAttributeBinding attributeBinding) {
|
final PluralAttributeBinding attributeBinding) {
|
||||||
return determineJavaType( attributeBinding.getAttribute() );
|
return determineJavaType( attributeBinding.getAttribute() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private scope methods
|
||||||
private Class<?> determineJavaType(final SingularAttribute attribute) {
|
private Class<?> determineJavaType(final SingularAttribute attribute) {
|
||||||
try {
|
try {
|
||||||
final Class<?> ownerClass = attribute.getAttributeContainer().getClassReference();
|
final Class<?> ownerClass = attribute.getAttributeContainer().getClassReference();
|
||||||
|
@ -181,29 +467,33 @@ public class HibernateTypeHelper {
|
||||||
private void bindHibernateTypeInformation(
|
private void bindHibernateTypeInformation(
|
||||||
final ExplicitHibernateTypeSource typeSource,
|
final ExplicitHibernateTypeSource typeSource,
|
||||||
final HibernateTypeDescriptor hibernateTypeDescriptor) {
|
final HibernateTypeDescriptor hibernateTypeDescriptor) {
|
||||||
|
|
||||||
final String explicitTypeName = typeSource.getName();
|
final String explicitTypeName = typeSource.getName();
|
||||||
|
|
||||||
if ( explicitTypeName != null ) {
|
if ( explicitTypeName != null ) {
|
||||||
final TypeDefinition typeDefinition = metadata.getTypeDefinition(
|
final TypeDefinition typeDefinition = metadata.getTypeDefinition(
|
||||||
explicitTypeName );
|
explicitTypeName
|
||||||
|
);
|
||||||
if ( typeDefinition != null ) {
|
if ( typeDefinition != null ) {
|
||||||
hibernateTypeDescriptor.setExplicitTypeName(
|
hibernateTypeDescriptor.setExplicitTypeName(
|
||||||
typeDefinition.getTypeImplementorClass().getName() );
|
typeDefinition.getTypeImplementorClass().getName()
|
||||||
|
);
|
||||||
// Don't use set() -- typeDef#parameters is unmodifiable
|
// Don't use set() -- typeDef#parameters is unmodifiable
|
||||||
hibernateTypeDescriptor.getTypeParameters().putAll(
|
hibernateTypeDescriptor.getTypeParameters().putAll(
|
||||||
typeDefinition.getParameters() );
|
typeDefinition.getParameters()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hibernateTypeDescriptor.setExplicitTypeName( explicitTypeName );
|
hibernateTypeDescriptor.setExplicitTypeName( explicitTypeName );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should type parameters be used for @TypeDefs?
|
// TODO: Should type parameters be used for @TypeDefs?
|
||||||
final Map<String, String> parameters = typeSource.getParameters();
|
final Map<String, String> parameters = typeSource.getParameters();
|
||||||
if ( parameters != null ) {
|
if ( parameters != null ) {
|
||||||
// Don't use set() -- typeDef#parameters is unmodifiable
|
// Don't use set() -- typeDef#parameters is unmodifiable
|
||||||
hibernateTypeDescriptor.getTypeParameters().putAll(
|
hibernateTypeDescriptor.getTypeParameters().putAll(
|
||||||
parameters );
|
parameters
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,8 +506,8 @@ public class HibernateTypeHelper {
|
||||||
* @param attributeBinding The attribute.
|
* @param attributeBinding The attribute.
|
||||||
*/
|
*/
|
||||||
private void processSingularAttributeTypeInformation(
|
private void processSingularAttributeTypeInformation(
|
||||||
SingularAttributeSource attributeSource,
|
final SingularAttributeSource attributeSource,
|
||||||
SingularAttributeBinding attributeBinding) {
|
final SingularAttributeBinding attributeBinding) {
|
||||||
Type resolvedType = attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping();
|
Type resolvedType = attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping();
|
||||||
|
|
||||||
if ( resolvedType == null ) {
|
if ( resolvedType == null ) {
|
||||||
|
@ -235,7 +525,8 @@ public class HibernateTypeHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type determineHibernateTypeFromDescriptor(HibernateTypeDescriptor hibernateTypeDescriptor) {
|
private Type determineHibernateTypeFromDescriptor(
|
||||||
|
final HibernateTypeDescriptor hibernateTypeDescriptor) {
|
||||||
if ( hibernateTypeDescriptor.getResolvedTypeMapping() != null ) {
|
if ( hibernateTypeDescriptor.getResolvedTypeMapping() != null ) {
|
||||||
return hibernateTypeDescriptor.getResolvedTypeMapping();
|
return hibernateTypeDescriptor.getResolvedTypeMapping();
|
||||||
}
|
}
|
||||||
|
@ -246,12 +537,14 @@ public class HibernateTypeHelper {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type getHeuristicType(String typeName, Properties typeParameters) {
|
private Type getHeuristicType(
|
||||||
|
final String typeName,
|
||||||
|
final Properties typeParameters) {
|
||||||
if ( typeName != null ) {
|
if ( typeName != null ) {
|
||||||
try {
|
try {
|
||||||
return metadata.getTypeResolver().heuristicType( typeName, typeParameters );
|
return metadata.getTypeResolver().heuristicType( typeName, typeParameters );
|
||||||
}
|
}
|
||||||
catch (Exception ignore) {
|
catch ( Exception ignore ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +553,8 @@ public class HibernateTypeHelper {
|
||||||
|
|
||||||
private static final Properties EMPTY_PROPERTIES = new Properties();
|
private static final Properties EMPTY_PROPERTIES = new Properties();
|
||||||
|
|
||||||
private Type determineHibernateTypeFromAttributeJavaType(SingularAttribute singularAttribute) {
|
private Type determineHibernateTypeFromAttributeJavaType(
|
||||||
|
final SingularAttribute singularAttribute) {
|
||||||
if ( singularAttribute.getSingularAttributeType() != null ) {
|
if ( singularAttribute.getSingularAttributeType() != null ) {
|
||||||
return getHeuristicType(
|
return getHeuristicType(
|
||||||
singularAttribute.getSingularAttributeType().getClassName(),
|
singularAttribute.getSingularAttributeType().getClassName(),
|
||||||
|
@ -270,27 +564,10 @@ public class HibernateTypeHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String determineTypeName(HibernateTypeDescriptor hibernateTypeDescriptor) {
|
|
||||||
return hibernateTypeDescriptor.getExplicitTypeName() != null
|
|
||||||
? hibernateTypeDescriptor.getExplicitTypeName()
|
|
||||||
: hibernateTypeDescriptor.getJavaTypeName();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Properties getTypeParameters(HibernateTypeDescriptor hibernateTypeDescriptor) {
|
|
||||||
if ( CollectionHelper.isEmpty( hibernateTypeDescriptor.getTypeParameters() ) ) {
|
|
||||||
return EMPTY_PROPERTIES;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Properties typeParameters = new Properties();
|
|
||||||
typeParameters.putAll( hibernateTypeDescriptor.getTypeParameters() );
|
|
||||||
return typeParameters;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void pushHibernateTypeInformationDown(
|
private void pushHibernateTypeInformationDown(
|
||||||
SingularAttributeSource attributeSource,
|
final SingularAttributeSource attributeSource,
|
||||||
SingularAttributeBinding attributeBinding,
|
final SingularAttributeBinding attributeBinding,
|
||||||
Type resolvedHibernateType) {
|
final Type resolvedHibernateType) {
|
||||||
|
|
||||||
// sql type information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// sql type information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
if ( BasicAttributeBinding.class.isInstance( attributeBinding ) ) {
|
if ( BasicAttributeBinding.class.isInstance( attributeBinding ) ) {
|
||||||
|
@ -309,14 +586,14 @@ public class HibernateTypeHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushHibernateTypeInformationDown(
|
private void pushHibernateTypeInformationDown(
|
||||||
BasicAttributeBinding attributeBinding,
|
final BasicAttributeBinding attributeBinding,
|
||||||
Type resolvedHibernateType) {
|
final Type resolvedHibernateType) {
|
||||||
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
|
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
|
||||||
final SingularAttribute singularAttribute = SingularAttribute.class.cast( attributeBinding.getAttribute() );
|
final SingularAttribute singularAttribute = SingularAttribute.class.cast( attributeBinding.getAttribute() );
|
||||||
if ( hibernateTypeDescriptor.getResolvedTypeMapping() != null && hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
if ( hibernateTypeDescriptor.getResolvedTypeMapping() != null && hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
||||||
hibernateTypeDescriptor.setJavaTypeName( resolvedHibernateType.getReturnedClass().getName() );
|
hibernateTypeDescriptor.setJavaTypeName( resolvedHibernateType.getReturnedClass().getName() );
|
||||||
}
|
}
|
||||||
if ( ! singularAttribute.isTypeResolved() && hibernateTypeDescriptor.getJavaTypeName() != null ) {
|
if ( !singularAttribute.isTypeResolved() && hibernateTypeDescriptor.getJavaTypeName() != null ) {
|
||||||
singularAttribute.resolveType( makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
|
singularAttribute.resolveType( makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
|
||||||
}
|
}
|
||||||
pushHibernateTypeInformationDown(
|
pushHibernateTypeInformationDown(
|
||||||
|
@ -326,14 +603,14 @@ public class HibernateTypeHelper {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( {"UnusedParameters"})
|
@SuppressWarnings({ "UnusedParameters" })
|
||||||
private void pushHibernateTypeInformationDown(
|
private void pushHibernateTypeInformationDown(
|
||||||
ComponentAttributeSource attributeSource,
|
final ComponentAttributeSource attributeSource,
|
||||||
CompositeAttributeBinding attributeBinding,
|
final CompositeAttributeBinding attributeBinding,
|
||||||
Type resolvedHibernateType) {
|
final Type resolvedHibernateType) {
|
||||||
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
|
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
|
||||||
final SingularAttribute singularAttribute = SingularAttribute.class.cast( attributeBinding.getAttribute() );
|
final SingularAttribute singularAttribute = SingularAttribute.class.cast( attributeBinding.getAttribute() );
|
||||||
if ( ! singularAttribute.isTypeResolved() && hibernateTypeDescriptor.getJavaTypeName() != null ) {
|
if ( !singularAttribute.isTypeResolved() && hibernateTypeDescriptor.getJavaTypeName() != null ) {
|
||||||
singularAttribute.resolveType( makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
|
singularAttribute.resolveType( makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,20 +619,23 @@ public class HibernateTypeHelper {
|
||||||
AttributeSource subAttributeSource = subAttributeSourceIterator.next();
|
AttributeSource subAttributeSource = subAttributeSourceIterator.next();
|
||||||
if ( SingularAttributeBinding.class.isInstance( subAttributeBinding ) ) {
|
if ( SingularAttributeBinding.class.isInstance( subAttributeBinding ) ) {
|
||||||
processSingularAttributeTypeInformation(
|
processSingularAttributeTypeInformation(
|
||||||
( SingularAttributeSource ) subAttributeSource,
|
(SingularAttributeSource) subAttributeSource,
|
||||||
SingularAttributeBinding.class.cast( subAttributeBinding )
|
SingularAttributeBinding.class.cast( subAttributeBinding )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new AssertionFailure( "Unknown type of AttributeBinding: " + attributeBinding.getClass().getName() );
|
throw new AssertionFailure(
|
||||||
|
"Unknown type of AttributeBinding: " + attributeBinding.getClass()
|
||||||
|
.getName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushHibernateTypeInformationDown(
|
private void pushHibernateTypeInformationDown(
|
||||||
HibernateTypeDescriptor hibernateTypeDescriptor,
|
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
||||||
List<RelationalValueBinding> relationalValueBindings,
|
final List<RelationalValueBinding> relationalValueBindings,
|
||||||
Type resolvedHibernateType) {
|
final Type resolvedHibernateType) {
|
||||||
if ( resolvedHibernateType == null ) {
|
if ( resolvedHibernateType == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -368,84 +648,66 @@ public class HibernateTypeHelper {
|
||||||
if ( hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
if ( hibernateTypeDescriptor.getJavaTypeName() == null ) {
|
||||||
hibernateTypeDescriptor.setJavaTypeName( resolvedHibernateType.getReturnedClass().getName() );
|
hibernateTypeDescriptor.setJavaTypeName( resolvedHibernateType.getReturnedClass().getName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
hibernateTypeDescriptor.setToOne( resolvedHibernateType.isEntityType() );
|
hibernateTypeDescriptor.setToOne( resolvedHibernateType.isEntityType() );
|
||||||
|
|
||||||
bindJdbcDataType( resolvedHibernateType, relationalValueBindings );
|
bindJdbcDataType( resolvedHibernateType, relationalValueBindings );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private org.hibernate.metamodel.spi.domain.Type makeJavaType(String name) {
|
||||||
* Bind relational types using hibernate type just resolved.
|
return binder.bindingContext().makeJavaType( name );
|
||||||
*
|
}
|
||||||
* @param resolvedHibernateType The hibernate type resolved from metadata.
|
|
||||||
* @param value The relational value to be binded.
|
private Type resolveCustomCollectionType(
|
||||||
*/
|
final PluralAttributeBinding pluralAttributeBinding) {
|
||||||
public void bindJdbcDataType(Type resolvedHibernateType, Value value) {
|
final HibernateTypeDescriptor hibernateTypeDescriptor = pluralAttributeBinding.getHibernateTypeDescriptor();
|
||||||
if ( value.getJdbcDataType() == null && resolvedHibernateType != null && value != null ) {
|
Properties typeParameters = new Properties();
|
||||||
final Type resolvedRelationalType =
|
typeParameters.putAll( hibernateTypeDescriptor.getTypeParameters() );
|
||||||
resolvedHibernateType.isEntityType()
|
return metadata.getTypeResolver().getTypeFactory().customCollection(
|
||||||
? EntityType.class.cast( resolvedHibernateType ).getIdentifierOrUniqueKeyType( metadata )
|
hibernateTypeDescriptor.getExplicitTypeName(),
|
||||||
: resolvedHibernateType;
|
typeParameters,
|
||||||
if ( AbstractValue.class.isInstance( value ) ) {
|
pluralAttributeBinding.getAttribute().getName(),
|
||||||
( (AbstractValue) value ).setJdbcDataType(
|
getReferencedPropertyNameIfNotId( pluralAttributeBinding ),
|
||||||
new JdbcDataType(
|
pluralAttributeBinding.getPluralAttributeElementBinding()
|
||||||
resolvedRelationalType.sqlTypes( metadata )[0],
|
.getNature() == PluralAttributeElementBinding.Nature.AGGREGATE
|
||||||
resolvedRelationalType.getName(),
|
);
|
||||||
resolvedRelationalType.getReturnedClass()
|
}
|
||||||
)
|
|
||||||
);
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private static methods
|
||||||
}
|
private static String determineTypeName(
|
||||||
|
final HibernateTypeDescriptor hibernateTypeDescriptor) {
|
||||||
|
return hibernateTypeDescriptor.getExplicitTypeName() != null
|
||||||
|
? hibernateTypeDescriptor.getExplicitTypeName()
|
||||||
|
: hibernateTypeDescriptor.getJavaTypeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Properties getTypeParameters(
|
||||||
|
final HibernateTypeDescriptor hibernateTypeDescriptor) {
|
||||||
|
if ( CollectionHelper.isEmpty( hibernateTypeDescriptor.getTypeParameters() ) ) {
|
||||||
|
return EMPTY_PROPERTIES;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Properties typeParameters = new Properties();
|
||||||
|
typeParameters.putAll( hibernateTypeDescriptor.getTypeParameters() );
|
||||||
|
return typeParameters;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindJdbcDataType(Type resolvedHibernateType, List<RelationalValueBinding> relationalValueBindings) {
|
private static String getReferencedPropertyNameIfNotId(
|
||||||
if ( relationalValueBindings.size() <= 1 ) {
|
final PluralAttributeBinding pluralAttributeBinding) {
|
||||||
bindJdbcDataType( resolvedHibernateType, relationalValueBindings.get( 0 ).getValue() );
|
EntityIdentifier entityIdentifier =
|
||||||
return;
|
pluralAttributeBinding.getContainer().seekEntityBinding().getHierarchyDetails().getEntityIdentifier();
|
||||||
}
|
final String idAttributeName =
|
||||||
final Type resolvedRelationalType =
|
entityIdentifier.getAttributeBinding().getAttribute().getName();
|
||||||
resolvedHibernateType.isEntityType()
|
return pluralAttributeBinding.getReferencedPropertyName().equals( idAttributeName ) ?
|
||||||
? EntityType.class.cast( resolvedHibernateType ).getIdentifierOrUniqueKeyType( metadata )
|
null :
|
||||||
: resolvedHibernateType;
|
pluralAttributeBinding.getReferencedPropertyName();
|
||||||
if ( !CompositeType.class.isInstance( resolvedRelationalType ) ) {
|
|
||||||
throw binder.bindingContext().makeMappingException( "Column number mismatch" ); // todo refine the exception message
|
|
||||||
}
|
|
||||||
Type[] subTypes = CompositeType.class.cast( resolvedRelationalType ).getSubtypes();
|
|
||||||
for ( int i = 0; i < subTypes.length; i++ ) {
|
|
||||||
bindJdbcDataType( subTypes[i], relationalValueBindings.get( i ).getValue() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* package-protected */
|
|
||||||
static class ReflectedCollectionJavaTypes {
|
|
||||||
private final Class<?> collectionType;
|
|
||||||
private final Class<?> collectionElementType;
|
|
||||||
private final Class<?> collectionIndexType;
|
|
||||||
|
|
||||||
private ReflectedCollectionJavaTypes(
|
|
||||||
Class<?> collectionType,
|
|
||||||
Class<?> collectionElementType,
|
|
||||||
Class<?> collectionIndexType) {
|
|
||||||
this.collectionType = collectionType;
|
|
||||||
this.collectionElementType = collectionElementType;
|
|
||||||
this.collectionIndexType = collectionIndexType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<?> getCollectionType() {
|
|
||||||
return collectionType;
|
|
||||||
}
|
|
||||||
public Class<?> getCollectionElementType() {
|
|
||||||
return collectionElementType;
|
|
||||||
}
|
|
||||||
public Class<?> getCollectionIndexType() {
|
|
||||||
return collectionIndexType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see HibernateTypeHelper#determineJavaType(PluralAttribute)
|
* @see HibernateTypeHelper#determineJavaType(PluralAttribute)
|
||||||
*/
|
*/
|
||||||
private class PluralAttributeJavaTypeDeterminerDelegate implements BeanInfoHelper.BeanInfoDelegate {
|
private static class PluralAttributeJavaTypeDeterminerDelegate implements BeanInfoHelper.BeanInfoDelegate {
|
||||||
private final Class<?> ownerClass;
|
private final Class<?> ownerClass;
|
||||||
private final String attributeName;
|
private final String attributeName;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue