HHH-8960 First cut of re-enabled BV integration
This commit is contained in:
parent
c46dbebc5b
commit
bf611d4e18
|
@ -26,7 +26,7 @@ package org.hibernate.cfg.beanvalidation;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
@ -41,8 +41,9 @@ import javax.validation.metadata.BeanDescriptor;
|
|||
import javax.validation.metadata.ConstraintDescriptor;
|
||||
import javax.validation.metadata.PropertyDescriptor;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
|
@ -52,16 +53,17 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.Selectable;
|
||||
import org.hibernate.mapping.SingleTableSubclass;
|
||||
import org.hibernate.metamodel.spi.binding.AbstractSingularAssociationAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.AbstractSingularAttributeBinding;
|
||||
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.InheritanceType;
|
||||
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
|
||||
import org.hibernate.metamodel.spi.domain.Attribute;
|
||||
import org.hibernate.metamodel.spi.domain.SingularAttribute;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.hibernate.metamodel.spi.relational.Column;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
|
@ -70,16 +72,19 @@ import org.jboss.logging.Logger;
|
|||
*/
|
||||
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.
|
||||
*
|
||||
* @param object The supplied ValidatorFactory instance.
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
@SuppressWarnings({ "UnusedDeclaration" })
|
||||
public static void validateSuppliedFactory(Object object) {
|
||||
if ( ! ValidatorFactory.class.isInstance( object ) ) {
|
||||
if ( !ValidatorFactory.class.isInstance( object ) ) {
|
||||
throw new IntegrationException(
|
||||
"Given object was not an instance of " + ValidatorFactory.class.getName()
|
||||
+ "[" + object.getClass().getName() + "]"
|
||||
|
@ -94,12 +99,18 @@ class TypeSafeActivator {
|
|||
try {
|
||||
factory = getValidatorFactory( activationContext );
|
||||
}
|
||||
catch (IntegrationException e) {
|
||||
catch ( IntegrationException e ) {
|
||||
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 ) ) {
|
||||
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" );
|
||||
|
@ -111,10 +122,10 @@ class TypeSafeActivator {
|
|||
applyCallbackListeners( factory, activationContext );
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
@SuppressWarnings({ "UnusedDeclaration" })
|
||||
public static void applyCallbackListeners(ValidatorFactory validatorFactory, ActivationContext activationContext) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -141,16 +152,15 @@ class TypeSafeActivator {
|
|||
listener.initialize( activationContext.getSettings() );
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "UnusedParameters"})
|
||||
private static void applyRelationalConstraints(ValidatorFactory factory, ActivationContext activationContext) {
|
||||
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" );
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -159,8 +169,6 @@ class TypeSafeActivator {
|
|||
Class<?>[] groupsArray = new GroupsPerOperation( properties ).get( GroupsPerOperation.Operation.DDL );
|
||||
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() ) {
|
||||
final String className = entityBinding.getEntity().getClassReference().getName();
|
||||
|
||||
|
@ -178,7 +186,7 @@ class TypeSafeActivator {
|
|||
try {
|
||||
applyDDL( "", entityBinding, clazz, factory, groups, true, dialect );
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch ( Exception e ) {
|
||||
LOG.unableToApplyConstraints( className, e );
|
||||
}
|
||||
}
|
||||
|
@ -193,43 +201,45 @@ class TypeSafeActivator {
|
|||
boolean activateNotNull,
|
||||
Dialect dialect) {
|
||||
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(
|
||||
entityBinding,
|
||||
prefix + propertyDesc.getPropertyName()
|
||||
prefix + propertyDescriptor.getPropertyName()
|
||||
);
|
||||
boolean hasNotNull;
|
||||
if ( attributeBinding != null ) {
|
||||
hasNotNull = applyConstraints(
|
||||
propertyDesc.getConstraintDescriptors(),
|
||||
attributeBinding,
|
||||
propertyDesc,
|
||||
groups,
|
||||
activateNotNull,
|
||||
dialect
|
||||
);
|
||||
if ( attributeBinding == null ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( propertyDesc.isCascaded() ) {
|
||||
// if it is a composite, visit its attributes
|
||||
final Attribute attribute = attributeBinding.getAttribute();
|
||||
if ( attribute.isSingular() ) {
|
||||
final SingularAttribute singularAttribute = (SingularAttribute) attribute;
|
||||
if ( singularAttribute.getSingularAttributeType().isAggregate() ) {
|
||||
final Class componentClass =
|
||||
singularAttribute.getSingularAttributeType().getClassReference().getResolvedClass();
|
||||
final boolean canSetNotNullOnColumns = activateNotNull && hasNotNull;
|
||||
applyDDL(
|
||||
prefix + propertyDesc.getPropertyName() + ".",
|
||||
entityBinding,
|
||||
componentClass,
|
||||
factory,
|
||||
groups,
|
||||
canSetNotNullOnColumns,
|
||||
dialect
|
||||
);
|
||||
}
|
||||
boolean hasNotNull;
|
||||
hasNotNull = applyConstraints(
|
||||
propertyDescriptor.getConstraintDescriptors(),
|
||||
attributeBinding,
|
||||
propertyDescriptor,
|
||||
groups,
|
||||
activateNotNull,
|
||||
dialect
|
||||
);
|
||||
|
||||
if ( propertyDescriptor.isCascaded() ) {
|
||||
// if it is a composite, visit its attributes
|
||||
final Attribute attribute = attributeBinding.getAttribute();
|
||||
if ( attribute.isSingular() ) {
|
||||
final SingularAttribute singularAttribute = (SingularAttribute) attribute;
|
||||
if ( singularAttribute.getSingularAttributeType().isAggregate() ) {
|
||||
final Class<?> componentClass = singularAttribute.getSingularAttributeType()
|
||||
.getClassReference().getResolvedClass();
|
||||
final boolean canSetNotNullOnColumns = activateNotNull && hasNotNull;
|
||||
applyDDL(
|
||||
prefix + propertyDescriptor.getPropertyName() + ".",
|
||||
entityBinding,
|
||||
componentClass,
|
||||
factory,
|
||||
groups,
|
||||
canSetNotNullOnColumns,
|
||||
dialect
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,8 +248,8 @@ class TypeSafeActivator {
|
|||
|
||||
private static boolean applyConstraints(
|
||||
Set<ConstraintDescriptor<?>> constraintDescriptors,
|
||||
AttributeBinding property,
|
||||
PropertyDescriptor propertyDesc,
|
||||
AttributeBinding attributeBinding,
|
||||
PropertyDescriptor propertyDescriptor,
|
||||
Set<Class<?>> groups,
|
||||
boolean canApplyNotNull,
|
||||
Dialect dialect) {
|
||||
|
@ -249,197 +259,184 @@ class TypeSafeActivator {
|
|||
continue;
|
||||
}
|
||||
|
||||
// todo : Hardy - here are the rabbit holes...
|
||||
// first...
|
||||
// if ( canApplyNotNull ) {
|
||||
// hasNotNull = hasNotNull || applyNotNull( property, descriptor );
|
||||
// }
|
||||
if ( canApplyNotNull ) {
|
||||
hasNotNull = hasNotNull || applyNotNull( attributeBinding, descriptor );
|
||||
}
|
||||
|
||||
// apply bean validation specific constraints
|
||||
// second...
|
||||
// applyDigits( property, descriptor );
|
||||
// applySize( property, descriptor, propertyDesc );
|
||||
// applyMin( property, descriptor, dialect );
|
||||
// applyMax( property, descriptor, dialect );
|
||||
applyDigits( attributeBinding, descriptor );
|
||||
applySize( attributeBinding, descriptor, propertyDescriptor );
|
||||
applyMin( attributeBinding, descriptor, dialect );
|
||||
applyMax( attributeBinding, descriptor, dialect );
|
||||
|
||||
// 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
|
||||
// will be taken care later
|
||||
// third
|
||||
// applyLength( property, descriptor, propertyDesc );
|
||||
applyLength( attributeBinding, descriptor );
|
||||
|
||||
// pass an empty set as composing constraints inherit the main constraint and thus are matching already
|
||||
hasNotNull = hasNotNull || applyConstraints(
|
||||
descriptor.getComposingConstraints(),
|
||||
property, propertyDesc, null,
|
||||
attributeBinding, propertyDescriptor, null,
|
||||
canApplyNotNull,
|
||||
dialect
|
||||
dialect
|
||||
);
|
||||
}
|
||||
return hasNotNull;
|
||||
}
|
||||
|
||||
private static void applyMin(Property property, ConstraintDescriptor<?> descriptor, Dialect dialect) {
|
||||
if ( Min.class.equals( descriptor.getAnnotation().annotationType() ) ) {
|
||||
@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();
|
||||
private static void applySQLCheck(Column column, String checkConstraint) {
|
||||
String existingCheck = column.getCheckCondition();
|
||||
// need to check whether the new check is already part of the existing check, because applyDDL can be called
|
||||
// multiple times
|
||||
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) {
|
||||
boolean hasNotNull = false;
|
||||
if ( NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) {
|
||||
// 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;
|
||||
private static boolean applyNotNull(AttributeBinding attributeBinding, ConstraintDescriptor<?> descriptor) {
|
||||
if ( !NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) {
|
||||
return false;
|
||||
}
|
||||
return hasNotNull;
|
||||
}
|
||||
|
||||
private static void applyDigits(Property property, ConstraintDescriptor<?> descriptor) {
|
||||
if ( Digits.class.equals( descriptor.getAnnotation().annotationType() ) ) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ConstraintDescriptor<Digits> digitsConstraint = (ConstraintDescriptor<Digits>) descriptor;
|
||||
int integerDigits = digitsConstraint.getAnnotation().integer();
|
||||
int fractionalDigits = digitsConstraint.getAnnotation().fraction();
|
||||
Column col = (Column) property.getColumnIterator().next();
|
||||
col.setPrecision( integerDigits + fractionalDigits );
|
||||
col.setScale( fractionalDigits );
|
||||
if ( InheritanceType.SINGLE_TABLE.equals(
|
||||
attributeBinding.getContainer()
|
||||
.seekEntityBinding()
|
||||
.getHierarchyDetails()
|
||||
.getInheritanceType()
|
||||
) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void applySize(Property property, ConstraintDescriptor<?> descriptor, PropertyDescriptor propertyDescriptor) {
|
||||
if ( Size.class.equals( descriptor.getAnnotation().annotationType() )
|
||||
&& String.class.equals( propertyDescriptor.getElementClass() ) ) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ConstraintDescriptor<Size> sizeConstraint = (ConstraintDescriptor<Size>) descriptor;
|
||||
int max = sizeConstraint.getAnnotation().max();
|
||||
Column col = (Column) property.getColumnIterator().next();
|
||||
if ( max < Integer.MAX_VALUE ) {
|
||||
col.setLength( max );
|
||||
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 applyLength(Property property, ConstraintDescriptor<?> descriptor, PropertyDescriptor propertyDescriptor) {
|
||||
if ( "org.hibernate.validator.constraints.Length".equals(
|
||||
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()
|
||||
)
|
||||
&& 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 );
|
||||
}
|
||||
) ) {
|
||||
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 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();
|
||||
private static void applyDigits(AttributeBinding attributeBinding, ConstraintDescriptor<?> descriptor) {
|
||||
if ( !Digits.class.equals( descriptor.getAnnotation().annotationType() ) ) {
|
||||
return;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
ConstraintDescriptor<Digits> digitsConstraint = (ConstraintDescriptor<Digits>) descriptor;
|
||||
int integerDigits = digitsConstraint.getAnnotation().integer();
|
||||
int fractionalDigits = digitsConstraint.getAnnotation().fraction();
|
||||
|
||||
Column column = getSingleColumn( attributeBinding );
|
||||
org.hibernate.metamodel.spi.relational.Size size = org.hibernate.metamodel.spi.relational.Size.precision(
|
||||
integerDigits + fractionalDigits,
|
||||
fractionalDigits
|
||||
);
|
||||
column.setSize( size );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code AttributeBinding} for the attribute/property specified by given path.
|
||||
*
|
||||
* @param entityBinding the root entity binding from which to start the search for the property
|
||||
* @param propertyPath the property path
|
||||
*
|
||||
* @return Returns the {@code AttributeBinding} for the attribute/property specified by given path. If
|
||||
* {@code propertyPath} is {@code null} or empty, the id attribute binding is returned.
|
||||
*/
|
||||
private static AttributeBinding findPropertyByName(EntityBinding entityBinding, String propertyPath) {
|
||||
final AttributeBinding idAttributeBinding = entityBinding.getHierarchyDetails()
|
||||
.getEntityIdentifier()
|
||||
.getAttributeBinding();
|
||||
final String idAttributeName = idAttributeBinding == null ? null : idAttributeBinding.getAttribute().getName();
|
||||
|
||||
AttributeBinding property = null;
|
||||
try {
|
||||
if ( propertyName == null
|
||||
|| propertyName.length() == 0
|
||||
|| propertyName.equals( idAttributeName ) ) {
|
||||
//default to id
|
||||
property = idAttributeBinding;
|
||||
if ( propertyPath == null || propertyPath.length() == 0 || propertyPath.equals( idAttributeName ) ) {
|
||||
//default to id
|
||||
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 {
|
||||
if ( propertyName.indexOf( idAttributeName + "." ) == 0 ) {
|
||||
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;
|
||||
}
|
||||
// todo : Hardy - not sure exactly what to do here...
|
||||
//property = ( (Component) property.getValue() ).getProperty( element );
|
||||
}
|
||||
if ( !isComposite( attributeBinding ) ) {
|
||||
return null;
|
||||
}
|
||||
CompositeAttributeBinding compositeAttributeBinding = (CompositeAttributeBinding) attributeBinding;
|
||||
attributeBinding = compositeAttributeBinding.locateAttributeBinding( element );
|
||||
}
|
||||
}
|
||||
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;
|
||||
return attributeBinding;
|
||||
}
|
||||
|
||||
private static boolean isComposite(AttributeBinding property) {
|
||||
|
@ -453,7 +450,9 @@ class TypeSafeActivator {
|
|||
|
||||
private static ValidatorFactory getValidatorFactory(ActivationContext activationContext) {
|
||||
// first look for an explicitly passed ValidatorFactory
|
||||
final Object reference = activationContext.getSessionFactory().getSessionFactoryOptions().getValidatorFactoryReference();
|
||||
final Object reference = activationContext.getSessionFactory()
|
||||
.getSessionFactoryOptions()
|
||||
.getValidatorFactoryReference();
|
||||
if ( reference != null ) {
|
||||
try {
|
||||
return ValidatorFactory.class.cast( reference );
|
||||
|
@ -473,4 +472,21 @@ class TypeSafeActivator {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue