HHH-8960 First cut of re-enabled BV integration

This commit is contained in:
Hardy Ferentschik 2014-02-11 14:22:39 +01:00
parent c46dbebc5b
commit bf611d4e18

View File

@ -26,7 +26,7 @@
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -41,8 +41,9 @@
import javax.validation.metadata.ConstraintDescriptor; import javax.validation.metadata.ConstraintDescriptor;
import javax.validation.metadata.PropertyDescriptor; import javax.validation.metadata.PropertyDescriptor;
import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.jdbc.spi.JdbcServices;
@ -52,16 +53,17 @@
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.mapping.Column; import org.hibernate.metamodel.spi.binding.AbstractSingularAssociationAttributeBinding;
import org.hibernate.mapping.Property; import org.hibernate.metamodel.spi.binding.AbstractSingularAttributeBinding;
import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.SingleTableSubclass;
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.CompositeAttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.InheritanceType;
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.domain.Attribute; import org.hibernate.metamodel.spi.domain.Attribute;
import org.hibernate.metamodel.spi.domain.SingularAttribute; import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.Column;
import org.jboss.logging.Logger;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
@ -70,16 +72,19 @@
*/ */
class TypeSafeActivator { class TypeSafeActivator {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TypeSafeActivator.class.getName()); private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
TypeSafeActivator.class.getName()
);
/** /**
* Used to validate a supplied ValidatorFactory instance as being castable to ValidatorFactory. * Used to validate a supplied ValidatorFactory instance as being castable to ValidatorFactory.
* *
* @param object The supplied ValidatorFactory instance. * @param object The supplied ValidatorFactory instance.
*/ */
@SuppressWarnings( {"UnusedDeclaration"}) @SuppressWarnings({ "UnusedDeclaration" })
public static void validateSuppliedFactory(Object object) { public static void validateSuppliedFactory(Object object) {
if ( ! ValidatorFactory.class.isInstance( object ) ) { if ( !ValidatorFactory.class.isInstance( object ) ) {
throw new IntegrationException( throw new IntegrationException(
"Given object was not an instance of " + ValidatorFactory.class.getName() "Given object was not an instance of " + ValidatorFactory.class.getName()
+ "[" + object.getClass().getName() + "]" + "[" + object.getClass().getName() + "]"
@ -94,12 +99,18 @@ public static void activate(ActivationContext activationContext) {
try { try {
factory = getValidatorFactory( activationContext ); factory = getValidatorFactory( activationContext );
} }
catch (IntegrationException e) { catch ( IntegrationException e ) {
if ( activationContext.getValidationModes().contains( ValidationMode.CALLBACK ) ) { if ( activationContext.getValidationModes().contains( ValidationMode.CALLBACK ) ) {
throw new IntegrationException( "Bean Validation provider was not available, but 'callback' validation was requested", e ); throw new IntegrationException(
"Bean Validation provider was not available, but 'callback' validation was requested",
e
);
} }
if ( activationContext.getValidationModes().contains( ValidationMode.DDL ) ) { if ( activationContext.getValidationModes().contains( ValidationMode.DDL ) ) {
throw new IntegrationException( "Bean Validation provider was not available, but 'ddl' validation was requested", e ); throw new IntegrationException(
"Bean Validation provider was not available, but 'ddl' validation was requested",
e
);
} }
LOG.debug( "Unable to acquire Bean Validation ValidatorFactory, skipping activation" ); LOG.debug( "Unable to acquire Bean Validation ValidatorFactory, skipping activation" );
@ -111,10 +122,10 @@ public static void activate(ActivationContext activationContext) {
applyCallbackListeners( factory, activationContext ); applyCallbackListeners( factory, activationContext );
} }
@SuppressWarnings( {"UnusedDeclaration"}) @SuppressWarnings({ "UnusedDeclaration" })
public static void applyCallbackListeners(ValidatorFactory validatorFactory, ActivationContext activationContext) { public static void applyCallbackListeners(ValidatorFactory validatorFactory, ActivationContext activationContext) {
final Set<ValidationMode> modes = activationContext.getValidationModes(); final Set<ValidationMode> modes = activationContext.getValidationModes();
if ( ! ( modes.contains( ValidationMode.CALLBACK ) || modes.contains( ValidationMode.AUTO ) ) ) { if ( !( modes.contains( ValidationMode.CALLBACK ) || modes.contains( ValidationMode.AUTO ) ) ) {
return; return;
} }
@ -141,16 +152,15 @@ public static void applyCallbackListeners(ValidatorFactory validatorFactory, Act
listener.initialize( activationContext.getSettings() ); listener.initialize( activationContext.getSettings() );
} }
@SuppressWarnings({"unchecked", "UnusedParameters"})
private static void applyRelationalConstraints(ValidatorFactory factory, ActivationContext activationContext) { private static void applyRelationalConstraints(ValidatorFactory factory, ActivationContext activationContext) {
final Map properties = activationContext.getSettings(); final Map properties = activationContext.getSettings();
if ( ! ConfigurationHelper.getBoolean( BeanValidationIntegrator.APPLY_CONSTRAINTS, properties, true ) ){ if ( !ConfigurationHelper.getBoolean( BeanValidationIntegrator.APPLY_CONSTRAINTS, properties, true ) ) {
LOG.debug( "Skipping application of relational constraints from legacy Hibernate Validator" ); LOG.debug( "Skipping application of relational constraints from legacy Hibernate Validator" );
return; return;
} }
final Set<ValidationMode> modes = activationContext.getValidationModes(); final Set<ValidationMode> modes = activationContext.getValidationModes();
if ( ! ( modes.contains( ValidationMode.DDL ) || modes.contains( ValidationMode.AUTO ) ) ) { if ( !( modes.contains( ValidationMode.DDL ) || modes.contains( ValidationMode.AUTO ) ) ) {
return; return;
} }
@ -159,8 +169,6 @@ private static void applyRelationalConstraints(ValidatorFactory factory, Activat
Class<?>[] groupsArray = new GroupsPerOperation( properties ).get( GroupsPerOperation.Operation.DDL ); Class<?>[] groupsArray = new GroupsPerOperation( properties ).get( GroupsPerOperation.Operation.DDL );
Set<Class<?>> groups = new HashSet<Class<?>>( Arrays.asList( groupsArray ) ); Set<Class<?>> groups = new HashSet<Class<?>>( Arrays.asList( groupsArray ) );
// Hardy : I started working on this as part of a big metamodel clean up I am doing, but this got to be too
// much of a rabbit hole. - Steve
for ( EntityBinding entityBinding : activationContext.getMetadata().getEntityBindings() ) { for ( EntityBinding entityBinding : activationContext.getMetadata().getEntityBindings() ) {
final String className = entityBinding.getEntity().getClassReference().getName(); final String className = entityBinding.getEntity().getClassReference().getName();
@ -178,7 +186,7 @@ private static void applyRelationalConstraints(ValidatorFactory factory, Activat
try { try {
applyDDL( "", entityBinding, clazz, factory, groups, true, dialect ); applyDDL( "", entityBinding, clazz, factory, groups, true, dialect );
} }
catch (Exception e) { catch ( Exception e ) {
LOG.unableToApplyConstraints( className, e ); LOG.unableToApplyConstraints( className, e );
} }
} }
@ -193,35 +201,38 @@ private static void applyDDL(
boolean activateNotNull, boolean activateNotNull,
Dialect dialect) { Dialect dialect) {
final BeanDescriptor descriptor = factory.getValidator().getConstraintsForClass( clazz ); final BeanDescriptor descriptor = factory.getValidator().getConstraintsForClass( clazz );
//no bean level constraints can be applied, go to the properties
for ( PropertyDescriptor propertyDesc : descriptor.getConstrainedProperties() ) { // no bean level constraints can be applied, just iterate the properties
for ( PropertyDescriptor propertyDescriptor : descriptor.getConstrainedProperties() ) {
AttributeBinding attributeBinding = findPropertyByName( AttributeBinding attributeBinding = findPropertyByName(
entityBinding, entityBinding,
prefix + propertyDesc.getPropertyName() prefix + propertyDescriptor.getPropertyName()
); );
if ( attributeBinding == null ) {
continue;
}
boolean hasNotNull; boolean hasNotNull;
if ( attributeBinding != null ) {
hasNotNull = applyConstraints( hasNotNull = applyConstraints(
propertyDesc.getConstraintDescriptors(), propertyDescriptor.getConstraintDescriptors(),
attributeBinding, attributeBinding,
propertyDesc, propertyDescriptor,
groups, groups,
activateNotNull, activateNotNull,
dialect dialect
); );
if ( propertyDesc.isCascaded() ) { if ( propertyDescriptor.isCascaded() ) {
// if it is a composite, visit its attributes // if it is a composite, visit its attributes
final Attribute attribute = attributeBinding.getAttribute(); final Attribute attribute = attributeBinding.getAttribute();
if ( attribute.isSingular() ) { if ( attribute.isSingular() ) {
final SingularAttribute singularAttribute = (SingularAttribute) attribute; final SingularAttribute singularAttribute = (SingularAttribute) attribute;
if ( singularAttribute.getSingularAttributeType().isAggregate() ) { if ( singularAttribute.getSingularAttributeType().isAggregate() ) {
final Class componentClass = final Class<?> componentClass = singularAttribute.getSingularAttributeType()
singularAttribute.getSingularAttributeType().getClassReference().getResolvedClass(); .getClassReference().getResolvedClass();
final boolean canSetNotNullOnColumns = activateNotNull && hasNotNull; final boolean canSetNotNullOnColumns = activateNotNull && hasNotNull;
applyDDL( applyDDL(
prefix + propertyDesc.getPropertyName() + ".", prefix + propertyDescriptor.getPropertyName() + ".",
entityBinding, entityBinding,
componentClass, componentClass,
factory, factory,
@ -234,12 +245,11 @@ private static void applyDDL(
} }
} }
} }
}
private static boolean applyConstraints( private static boolean applyConstraints(
Set<ConstraintDescriptor<?>> constraintDescriptors, Set<ConstraintDescriptor<?>> constraintDescriptors,
AttributeBinding property, AttributeBinding attributeBinding,
PropertyDescriptor propertyDesc, PropertyDescriptor propertyDescriptor,
Set<Class<?>> groups, Set<Class<?>> groups,
boolean canApplyNotNull, boolean canApplyNotNull,
Dialect dialect) { Dialect dialect) {
@ -249,29 +259,25 @@ private static boolean applyConstraints(
continue; continue;
} }
// todo : Hardy - here are the rabbit holes... if ( canApplyNotNull ) {
// first... hasNotNull = hasNotNull || applyNotNull( attributeBinding, descriptor );
// if ( canApplyNotNull ) { }
// hasNotNull = hasNotNull || applyNotNull( property, descriptor );
// }
// apply bean validation specific constraints // apply bean validation specific constraints
// second... applyDigits( attributeBinding, descriptor );
// applyDigits( property, descriptor ); applySize( attributeBinding, descriptor, propertyDescriptor );
// applySize( property, descriptor, propertyDesc ); applyMin( attributeBinding, descriptor, dialect );
// applyMin( property, descriptor, dialect ); applyMax( attributeBinding, descriptor, dialect );
// applyMax( property, descriptor, dialect );
// apply hibernate validator specific constraints - we cannot import any HV specific classes though! // apply hibernate validator specific constraints - we cannot import any HV specific classes though!
// no need to check explicitly for @Range. @Range is a composed constraint using @Min and @Max which // no need to check explicitly for @Range. @Range is a composed constraint using @Min and @Max which
// will be taken care later // will be taken care later
// third applyLength( attributeBinding, descriptor );
// applyLength( property, descriptor, propertyDesc );
// pass an empty set as composing constraints inherit the main constraint and thus are matching already // pass an empty set as composing constraints inherit the main constraint and thus are matching already
hasNotNull = hasNotNull || applyConstraints( hasNotNull = hasNotNull || applyConstraints(
descriptor.getComposingConstraints(), descriptor.getComposingConstraints(),
property, propertyDesc, null, attributeBinding, propertyDescriptor, null,
canApplyNotNull, canApplyNotNull,
dialect dialect
); );
@ -279,167 +285,158 @@ private static boolean applyConstraints(
return hasNotNull; return hasNotNull;
} }
private static void applyMin(Property property, ConstraintDescriptor<?> descriptor, Dialect dialect) { private static void applySQLCheck(Column column, String checkConstraint) {
if ( Min.class.equals( descriptor.getAnnotation().annotationType() ) ) { String existingCheck = column.getCheckCondition();
@SuppressWarnings("unchecked")
ConstraintDescriptor<Min> minConstraint = (ConstraintDescriptor<Min>) descriptor;
long min = minConstraint.getAnnotation().value();
Column col = (Column) property.getColumnIterator().next();
String checkConstraint = col.getQuotedName(dialect) + ">=" + min;
applySQLCheck( col, checkConstraint );
}
}
private static void applyMax(Property property, ConstraintDescriptor<?> descriptor, Dialect dialect) {
if ( Max.class.equals( descriptor.getAnnotation().annotationType() ) ) {
@SuppressWarnings("unchecked")
ConstraintDescriptor<Max> maxConstraint = (ConstraintDescriptor<Max>) descriptor;
long max = maxConstraint.getAnnotation().value();
Column col = (Column) property.getColumnIterator().next();
String checkConstraint = col.getQuotedName(dialect) + "<=" + max;
applySQLCheck( col, checkConstraint );
}
}
private static void applySQLCheck(Column col, String checkConstraint) {
String existingCheck = col.getCheckConstraint();
// need to check whether the new check is already part of the existing check, because applyDDL can be called // need to check whether the new check is already part of the existing check, because applyDDL can be called
// multiple times // multiple times
if ( StringHelper.isNotEmpty( existingCheck ) && !existingCheck.contains( checkConstraint ) ) { if ( StringHelper.isNotEmpty( existingCheck ) && !existingCheck.contains( checkConstraint ) ) {
checkConstraint = col.getCheckConstraint() + " AND " + checkConstraint; checkConstraint = column.getCheckCondition() + " AND " + checkConstraint;
} }
col.setCheckConstraint( checkConstraint ); column.setCheckCondition( checkConstraint );
} }
private static boolean applyNotNull(Property property, ConstraintDescriptor<?> descriptor) { private static boolean applyNotNull(AttributeBinding attributeBinding, ConstraintDescriptor<?> descriptor) {
boolean hasNotNull = false; if ( !NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) {
if ( NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) { return false;
// single table inheritance should not be forced to null due to shared state
if ( !( property.getPersistentClass() instanceof SingleTableSubclass ) ) {
//composite should not add not-null on all columns
if ( !property.isComposite() ) {
final Iterator<Selectable> iter = property.getColumnIterator();
while ( iter.hasNext() ) {
final Selectable selectable = iter.next();
if ( Column.class.isInstance( selectable ) ) {
Column.class.cast( selectable ).setNullable( false );
}
else {
LOG.debugf(
"@NotNull was applied to attribute [%s] which is defined (at least partially) " +
"by formula(s); formula portions will be skipped",
property.getName()
);
}
}
}
}
hasNotNull = true;
}
return hasNotNull;
} }
private static void applyDigits(Property property, ConstraintDescriptor<?> descriptor) { if ( InheritanceType.SINGLE_TABLE.equals(
if ( Digits.class.equals( descriptor.getAnnotation().annotationType() ) ) { attributeBinding.getContainer()
.seekEntityBinding()
.getHierarchyDetails()
.getInheritanceType()
) ) {
return false;
}
List<RelationalValueBinding> relationalValueBindings = Collections.emptyList();
if ( attributeBinding instanceof BasicAttributeBinding ) {
BasicAttributeBinding basicBinding = (BasicAttributeBinding) attributeBinding;
relationalValueBindings = basicBinding.getRelationalValueBindings();
}
if ( attributeBinding instanceof AbstractSingularAssociationAttributeBinding ) {
AbstractSingularAssociationAttributeBinding singularAttributeBinding = (AbstractSingularAssociationAttributeBinding) attributeBinding;
relationalValueBindings = singularAttributeBinding.getRelationalValueBindings();
}
if ( attributeBinding instanceof AbstractSingularAttributeBinding ) {
AbstractSingularAttributeBinding singularAttributeBinding = (AbstractSingularAttributeBinding) attributeBinding;
relationalValueBindings = singularAttributeBinding.getRelationalValueBindings();
}
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
if ( relationalValueBinding.getValue() instanceof Column ) {
Column column = (Column) relationalValueBinding.getValue();
column.setNullable( false );
}
}
return true;
}
private static void applyMin(AttributeBinding attributeBinding, ConstraintDescriptor<?> descriptor, Dialect dialect) {
if ( !Min.class.equals( descriptor.getAnnotation().annotationType() ) ) {
return;
}
long min = (Long) descriptor.getAttributes().get( "value" );
Column column = getSingleColumn( attributeBinding );
String checkConstraint = column.getColumnName().getText( dialect ) + ">=" + min;
applySQLCheck( column, checkConstraint );
}
private static void applyMax(AttributeBinding attributeBinding, ConstraintDescriptor<?> descriptor, Dialect dialect) {
if ( !Max.class.equals( descriptor.getAnnotation().annotationType() ) ) {
return;
}
long max = (Long) descriptor.getAttributes().get( "value" );
Column column = getSingleColumn( attributeBinding );
String checkConstraint = column.getColumnName().getText( dialect ) + "<=" + max;
applySQLCheck( column, checkConstraint );
}
private static void applySize(AttributeBinding attributeBinding, ConstraintDescriptor<?> descriptor, PropertyDescriptor propertyDescriptor) {
if ( !( Size.class.equals( descriptor.getAnnotation().annotationType() )
&& String.class.equals( propertyDescriptor.getElementClass() ) ) ) {
return;
}
int max = (Integer) descriptor.getAttributes().get( "max" );
Column column = getSingleColumn( attributeBinding );
if ( max < Integer.MAX_VALUE ) {
column.setSize( org.hibernate.metamodel.spi.relational.Size.length( max ) );
}
}
private static void applyLength(AttributeBinding attributeBinding, ConstraintDescriptor<?> descriptor) {
if ( !"org.hibernate.validator.constraints.Length".equals(
descriptor.getAnnotation().annotationType().getName()
) ) {
return;
}
int max = (Integer) descriptor.getAttributes().get( "max" );
Column column = getSingleColumn( attributeBinding );
if ( max < Integer.MAX_VALUE ) {
column.setSize( org.hibernate.metamodel.spi.relational.Size.length( max ) );
}
}
private static void applyDigits(AttributeBinding attributeBinding, ConstraintDescriptor<?> descriptor) {
if ( !Digits.class.equals( descriptor.getAnnotation().annotationType() ) ) {
return;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ConstraintDescriptor<Digits> digitsConstraint = (ConstraintDescriptor<Digits>) descriptor; ConstraintDescriptor<Digits> digitsConstraint = (ConstraintDescriptor<Digits>) descriptor;
int integerDigits = digitsConstraint.getAnnotation().integer(); int integerDigits = digitsConstraint.getAnnotation().integer();
int fractionalDigits = digitsConstraint.getAnnotation().fraction(); int fractionalDigits = digitsConstraint.getAnnotation().fraction();
Column col = (Column) property.getColumnIterator().next();
col.setPrecision( integerDigits + fractionalDigits ); Column column = getSingleColumn( attributeBinding );
col.setScale( fractionalDigits ); org.hibernate.metamodel.spi.relational.Size size = org.hibernate.metamodel.spi.relational.Size.precision(
} integerDigits + fractionalDigits,
fractionalDigits
);
column.setSize( size );
} }
private static void applySize(Property property, ConstraintDescriptor<?> descriptor, PropertyDescriptor propertyDescriptor) { /**
if ( Size.class.equals( descriptor.getAnnotation().annotationType() ) * Returns the {@code AttributeBinding} for the attribute/property specified by given path.
&& String.class.equals( propertyDescriptor.getElementClass() ) ) { *
@SuppressWarnings("unchecked") * @param entityBinding the root entity binding from which to start the search for the property
ConstraintDescriptor<Size> sizeConstraint = (ConstraintDescriptor<Size>) descriptor; * @param propertyPath the property path
int max = sizeConstraint.getAnnotation().max(); *
Column col = (Column) property.getColumnIterator().next(); * @return Returns the {@code AttributeBinding} for the attribute/property specified by given path. If
if ( max < Integer.MAX_VALUE ) { * {@code propertyPath} is {@code null} or empty, the id attribute binding is returned.
col.setLength( max ); */
} private static AttributeBinding findPropertyByName(EntityBinding entityBinding, String propertyPath) {
} final AttributeBinding idAttributeBinding = entityBinding.getHierarchyDetails()
} .getEntityIdentifier()
.getAttributeBinding();
private static void applyLength(Property property, ConstraintDescriptor<?> descriptor, PropertyDescriptor propertyDescriptor) {
if ( "org.hibernate.validator.constraints.Length".equals(
descriptor.getAnnotation().annotationType().getName()
)
&& String.class.equals( propertyDescriptor.getElementClass() ) ) {
@SuppressWarnings("unchecked")
int max = (Integer) descriptor.getAttributes().get( "max" );
Column col = (Column) property.getColumnIterator().next();
if ( max < Integer.MAX_VALUE ) {
col.setLength( max );
}
}
}
private static AttributeBinding findPropertyByName(EntityBinding entityBinding, String propertyName) {
// Returns the property by path in a recursive way, including IdentifierProperty in the loop
// if propertyName is null. If propertyName is null or empty, the IdentifierProperty is returned
final AttributeBinding idAttributeBinding = entityBinding.getHierarchyDetails().getEntityIdentifier().getAttributeBinding();
final String idAttributeName = idAttributeBinding == null ? null : idAttributeBinding.getAttribute().getName(); final String idAttributeName = idAttributeBinding == null ? null : idAttributeBinding.getAttribute().getName();
AttributeBinding property = null; if ( propertyPath == null || propertyPath.length() == 0 || propertyPath.equals( idAttributeName ) ) {
try {
if ( propertyName == null
|| propertyName.length() == 0
|| propertyName.equals( idAttributeName ) ) {
//default to id //default to id
property = idAttributeBinding; return idAttributeBinding;
}
AttributeBinding attributeBinding = null;
StringTokenizer tokenizer = new StringTokenizer( propertyPath, ".", false );
while ( tokenizer.hasMoreElements() ) {
String element = (String) tokenizer.nextElement();
if ( attributeBinding == null ) {
attributeBinding = entityBinding.locateAttributeBinding( element );
} }
else { else {
if ( propertyName.indexOf( idAttributeName + "." ) == 0 ) { if ( !isComposite( attributeBinding ) ) {
property = idAttributeBinding;
propertyName = propertyName.substring( idAttributeName.length() + 1 );
}
StringTokenizer st = new StringTokenizer( propertyName, ".", false );
while ( st.hasMoreElements() ) {
String element = (String) st.nextElement();
if ( property == null ) {
property = entityBinding.locateAttributeBinding( element );
}
else {
if ( !isComposite( property ) ) {
return null; return null;
} }
// todo : Hardy - not sure exactly what to do here... CompositeAttributeBinding compositeAttributeBinding = (CompositeAttributeBinding) attributeBinding;
//property = ( (Component) property.getValue() ).getProperty( element ); attributeBinding = compositeAttributeBinding.locateAttributeBinding( element );
} }
} }
} return attributeBinding;
}
catch ( MappingException e ) {
// todo : Hardy - nor here...
// try {
// //if we do not find it try to check the identifier mapper
// if ( associatedClass.getIdentifierMapper() == null ) {
// return null;
// }
// StringTokenizer st = new StringTokenizer( propertyName, ".", false );
// while ( st.hasMoreElements() ) {
// String element = (String) st.nextElement();
// if ( property == null ) {
// property = associatedClass.getIdentifierMapper().getProperty( element );
// }
// else {
// if ( !property.isComposite() ) {
// return null;
// }
// property = ( (Component) property.getValue() ).getProperty( element );
// }
// }
// }
// catch ( MappingException ee ) {
// return null;
// }
}
return property;
} }
private static boolean isComposite(AttributeBinding property) { private static boolean isComposite(AttributeBinding property) {
@ -453,7 +450,9 @@ private static boolean isComposite(AttributeBinding property) {
private static ValidatorFactory getValidatorFactory(ActivationContext activationContext) { private static ValidatorFactory getValidatorFactory(ActivationContext activationContext) {
// first look for an explicitly passed ValidatorFactory // first look for an explicitly passed ValidatorFactory
final Object reference = activationContext.getSessionFactory().getSessionFactoryOptions().getValidatorFactoryReference(); final Object reference = activationContext.getSessionFactory()
.getSessionFactoryOptions()
.getValidatorFactoryReference();
if ( reference != null ) { if ( reference != null ) {
try { try {
return ValidatorFactory.class.cast( reference ); return ValidatorFactory.class.cast( reference );
@ -473,4 +472,21 @@ private static ValidatorFactory getValidatorFactory(ActivationContext activation
throw new IntegrationException( "Unable to build the default ValidatorFactory", e ); throw new IntegrationException( "Unable to build the default ValidatorFactory", e );
} }
} }
private static Column getSingleColumn(AttributeBinding attributeBinding) {
BasicAttributeBinding basicBinding = (BasicAttributeBinding) attributeBinding;
List<RelationalValueBinding> relationalValueBindings = basicBinding.getRelationalValueBindings();
if ( relationalValueBindings.size() > 1 ) {
throw new IntegrationException(
"Unexpected number of relational columns for attribute "
+ attributeBinding.getAttribute().getName()
);
}
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
if ( relationalValueBinding.getValue() instanceof Column ) {
return (Column) relationalValueBinding.getValue();
}
}
return null;
}
} }