HHH-10069 - ClassCastException between CompositeCustomType and ComponentType part 2

This commit is contained in:
Steve Ebersole 2015-09-01 21:31:27 -05:00
parent 8916346b4a
commit 961b5e8977
12 changed files with 88 additions and 40 deletions

View File

@ -40,6 +40,7 @@ import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.IntegerType;
import org.hibernate.type.LongType;
import org.hibernate.type.PostgresUUIDType;
@ -686,8 +687,8 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
// the param would have to be bound twice. Until we eventually add "parameter bind points" concepts to the
// AST in ORM 5+, handling this type of condition is either extremely difficult or impossible. Forcing
// recreation isn't ideal, but not really any other option in ORM 4.
if (persister.getElementType() instanceof ComponentType) {
ComponentType componentType = (ComponentType) persister.getElementType();
if ( persister.getElementType() instanceof CompositeType ) {
CompositeType componentType = (CompositeType) persister.getElementType();
return !componentType.hasNotNullProperty();
}
return false;

View File

@ -78,6 +78,7 @@ import org.hibernate.persister.entity.Queryable;
import org.hibernate.sql.JoinType;
import org.hibernate.type.AssociationType;
import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.DbTimestampType;
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
@ -389,7 +390,7 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
null,
false
);
fromElement = factory.createComponentJoin( (ComponentType) dot.getDataType() );
fromElement = factory.createComponentJoin( (CompositeType) dot.getDataType() );
}
else {
fromElement = dot.getImpliedJoin();

View File

@ -11,7 +11,7 @@ import org.hibernate.hql.internal.NameGenerator;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.Type;
/**
@ -21,7 +21,7 @@ import org.hibernate.type.Type;
*/
public class ComponentJoin extends FromElement {
private final String componentPath;
private final ComponentType componentType;
private final CompositeType componentType;
private final String componentProperty;
private final String[] columns;
@ -32,7 +32,7 @@ public class ComponentJoin extends FromElement {
FromElement origin,
String alias,
String componentPath,
ComponentType componentType) {
CompositeType componentType) {
super( fromClause, origin, alias );
this.componentPath = componentPath;
this.componentType = componentType;
@ -60,7 +60,7 @@ public class ComponentJoin extends FromElement {
return componentProperty;
}
public ComponentType getComponentType() {
public CompositeType getComponentType() {
return componentType;
}

View File

@ -22,7 +22,7 @@ import org.hibernate.persister.entity.Queryable;
import org.hibernate.sql.JoinType;
import org.hibernate.type.AssociationType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
@ -286,7 +286,7 @@ public class FromElementFactory implements SqlTokenTypes {
return elem;
}
public FromElement createComponentJoin(ComponentType type) {
public FromElement createComponentJoin(CompositeType type) {
// need to create a "place holder" from-element that can store the component/alias for this
// component join

View File

@ -15,7 +15,7 @@ import java.util.Set;
import org.hibernate.QueryException;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.Type;
import antlr.collections.AST;
@ -157,9 +157,9 @@ public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode {
}
if ( !explicitIdInsertion ) {
if ( persister.getIdentifierType() instanceof ComponentType ) {
if ( persister.getIdentifierType() instanceof CompositeType ) {
if ( componentIds == null ) {
String[] propertyNames = ( (ComponentType) persister.getIdentifierType() ).getPropertyNames();
String[] propertyNames = ( (CompositeType) persister.getIdentifierType() ).getPropertyNames();
componentIds = new HashSet();
for ( int i = 0; i < propertyNames.length; i++ ) {
componentIds.add( propertyNames[i] );

View File

@ -12,7 +12,7 @@ import java.util.Map;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.Type;
/**
@ -29,7 +29,7 @@ class ComponentCollectionCriteriaInfoProvider implements CriteriaInfoProvider {
throw new IllegalArgumentException( "persister for role " + persister.getRole() + " is not a collection-of-component" );
}
ComponentType componentType = (ComponentType) persister.getElementType();
CompositeType componentType = (CompositeType) persister.getElementType();
String[] names = componentType.getPropertyNames();
Type[] types = componentType.getSubtypes();

View File

@ -34,7 +34,6 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Joinable;
import org.hibernate.persister.entity.OuterJoinLoadable;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.type.ComponentType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.Type;
@ -247,7 +246,7 @@ public class EntityLoadQueryDetails extends AbstractLoadQueryDetails {
( (Session) context.getSession() ).buildLockRequest( LockOptions.NONE ).lock( subValue );
}
else if ( subType.isComponentType() ) {
addKeyManyToOnesToSession( context, (ComponentType) subType, subValue );
addKeyManyToOnesToSession( context, (CompositeType) subType, subValue );
}
}
}

View File

@ -37,7 +37,7 @@ public interface ProxyFactory {
* @param setIdentifierMethod Reference to the identifier setter method;
* invocation on this method should not force initialization
* @param componentIdType For composite identifier types, a reference to
* the {@link org.hibernate.type.ComponentType type} of the identifier
* the {@link org.hibernate.type.CompositeType type} of the identifier
* property; again accessing the id should generally not cause
* initialization - but need to bear in mind <key-many-to-one/>
* mappings.

View File

@ -20,6 +20,7 @@ import org.hibernate.EntityNameResolver;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.TransientObjectException;
import org.hibernate.engine.internal.ForeignKeys;
import org.hibernate.engine.jdbc.Size;
@ -35,8 +36,6 @@ import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.HibernateProxyHelper;
import org.hibernate.proxy.LazyInitializer;
import org.dom4j.Node;
/**
* Handles "any" mappings
*
@ -49,9 +48,6 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT
/**
* Intended for use only from legacy {@link ObjectType} type definition
*
* @param discriminatorType
* @param identifierType
*/
protected AnyType(Type discriminatorType, Type identifierType) {
this( null, discriminatorType, identifierType );
@ -375,6 +371,18 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT
return PROPERTY_NAMES;
}
@Override
public int getPropertyIndex(String name) {
if ( PROPERTY_NAMES[0].equals( name ) ) {
return 0;
}
else if ( PROPERTY_NAMES[1].equals( name ) ) {
return 1;
}
throw new PropertyNotFoundException( "Unable to locate property named " + name + " on AnyType" );
}
@Override
public Object getPropertyValue(Object component, int i, SessionImplementor session) throws HibernateException {
return i==0
@ -415,6 +423,12 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT
return NULLABILITY;
}
@Override
public boolean hasNotNullProperty() {
// both are non-nullable
return true;
}
@Override
public Type[] getSubtypes() {
return new Type[] {discriminatorType, identifierType };

View File

@ -31,9 +31,6 @@ import org.hibernate.tuple.StandardProperty;
import org.hibernate.tuple.component.ComponentMetamodel;
import org.hibernate.tuple.component.ComponentTuplizer;
import org.dom4j.Element;
import org.dom4j.Node;
/**
* Handles "component" mappings
*
@ -723,6 +720,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced
return false;
}
@Override
public int getPropertyIndex(String name) {
String[] names = getPropertyNames();
for ( int i = 0, max = names.length; i < max; i++ ) {
@ -817,6 +815,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced
return resolve( values, session, null );
}
@Override
public boolean hasNotNullProperty() {
return hasNotNullProperty;
}

View File

@ -17,19 +17,17 @@ import org.hibernate.EntityMode;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadeStyles;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.LoggableUserType;
import org.dom4j.Element;
import org.dom4j.Node;
/**
* Adapts {@link CompositeUserType} to the {@link Type} interface
*
@ -73,6 +71,19 @@ public class CompositeCustomType extends AbstractType implements CompositeType,
return userType.getPropertyNames();
}
@Override
public int getPropertyIndex(String name) {
String[] names = getPropertyNames();
for ( int i = 0, max = names.length; i < max; i++ ) {
if ( names[i].equals( name ) ) {
return i;
}
}
throw new PropertyNotFoundException(
"Unable to locate property named " + name + " on " + getReturnedClass().getName()
);
}
public Object[] getPropertyValues(Object component, SessionImplementor session) throws HibernateException {
return getPropertyValues( component, EntityMode.POJO );
}
@ -278,4 +289,10 @@ public class CompositeCustomType extends AbstractType implements CompositeType,
public boolean isEmbedded() {
return false;
}
@Override
public boolean hasNotNullProperty() {
// We just don't know. So assume nullable
return false;
}
}

View File

@ -26,14 +26,14 @@ public interface CompositeType extends Type {
*
* @return The component property types.
*/
public Type[] getSubtypes();
Type[] getSubtypes();
/**
* Get the names of the component properties
*
* @return The component property names
*/
public String[] getPropertyNames();
String[] getPropertyNames();
/**
* Retrieve the indicators regarding which component properties are nullable.
@ -42,7 +42,7 @@ public interface CompositeType extends Type {
*
* @return nullability of component properties
*/
public boolean[] getPropertyNullability();
boolean[] getPropertyNullability();
/**
* Extract the values of the component properties from the given component instance
@ -54,7 +54,7 @@ public interface CompositeType extends Type {
*
* @throws HibernateException Indicates a problem access the property values.
*/
public Object[] getPropertyValues(Object component, SessionImplementor session) throws HibernateException;
Object[] getPropertyValues(Object component, SessionImplementor session) throws HibernateException;
/**
* Extract the values of the component properties from the given component instance without access to the
@ -69,7 +69,7 @@ public interface CompositeType extends Type {
*
* @throws HibernateException Indicates a problem access the property values.
*/
public Object[] getPropertyValues(Object component, EntityMode entityMode) throws HibernateException;
Object[] getPropertyValues(Object component, EntityMode entityMode) throws HibernateException;
/**
* Extract a particular component property value indicated by index.
@ -82,7 +82,7 @@ public interface CompositeType extends Type {
*
* @throws HibernateException Indicates a problem access the property value.
*/
public Object getPropertyValue(Object component, int index, SessionImplementor session) throws HibernateException;
Object getPropertyValue(Object component, int index, SessionImplementor session) throws HibernateException;
/**
* Inject property values onto the given component instance
@ -95,7 +95,7 @@ public interface CompositeType extends Type {
*
* @throws HibernateException Indicates an issue performing the injection
*/
public void setPropertyValues(Object component, Object[] values, EntityMode entityMode) throws HibernateException;
void setPropertyValues(Object component, Object[] values, EntityMode entityMode) throws HibernateException;
/**
* Retrieve the cascade style of the indicated component property.
@ -104,7 +104,7 @@ public interface CompositeType extends Type {
*
* @return The cascade style.
*/
public CascadeStyle getCascadeStyle(int index);
CascadeStyle getCascadeStyle(int index);
/**
* Retrieve the fetch mode of the indicated component property.
@ -113,7 +113,7 @@ public interface CompositeType extends Type {
*
* @return The fetch mode
*/
public FetchMode getFetchMode(int index);
FetchMode getFetchMode(int index);
/**
* Is the given method a member of this component's class?
@ -122,7 +122,7 @@ public interface CompositeType extends Type {
*
* @return True if the method is a member; false otherwise.
*/
public boolean isMethodOf(Method method);
boolean isMethodOf(Method method);
/**
* Is this component embedded? "embedded" indicates that the component is "virtual", that its properties are
@ -130,5 +130,22 @@ public interface CompositeType extends Type {
*
* @return True if this component is embedded; false otherwise.
*/
public boolean isEmbedded();
boolean isEmbedded();
/**
* Convenience method to quickly check {@link #getPropertyNullability} for any non-nullable sub-properties.
*
* @return {@code true} if any of the properties are not-nullable as indicated by {@link #getPropertyNullability},
* {@code false} otherwise.
*/
boolean hasNotNullProperty();
/**
* Convenience method for locating the property index for a given property name.
*
* @param propertyName The (sub-)property name to find.
*
* @return The (sub-)property index, relative to all the array-valued method returns defined on this contract.
*/
int getPropertyIndex(String propertyName);
}