| 
11 | 11 | import java.util.Collections;  | 
12 | 12 | import java.util.HashSet;  | 
13 | 13 | import java.util.Iterator;  | 
 | 14 | +import java.util.Locale;  | 
14 | 15 | import java.util.Map;  | 
15 | 16 | import java.util.Set;  | 
16 | 17 | import java.util.StringTokenizer;  | 
 | 
31 | 32 | import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;  | 
32 | 33 | import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;  | 
33 | 34 | import org.hibernate.boot.spi.ClassLoaderAccess;  | 
 | 35 | +import org.hibernate.boot.spi.SessionFactoryOptions;  | 
34 | 36 | import org.hibernate.cfg.Environment;  | 
35 | 37 | import org.hibernate.dialect.Dialect;  | 
36 | 38 | import org.hibernate.engine.config.spi.ConfigurationService;  | 
@@ -77,10 +79,9 @@ public static void validateSuppliedFactory(Object object) {  | 
77 | 79 | 
 
  | 
78 | 80 | 	@SuppressWarnings("UnusedDeclaration")  | 
79 | 81 | 	public static void activate(ActivationContext activationContext) {  | 
80 |  | -		final ConfigurationService cfgService = activationContext.getServiceRegistry().getService( ConfigurationService.class );  | 
81 | 82 | 		final ValidatorFactory factory;  | 
82 | 83 | 		try {  | 
83 |  | -			factory = getValidatorFactory( cfgService.getSettings() );  | 
 | 84 | +			factory = getValidatorFactory( activationContext );  | 
84 | 85 | 		}  | 
85 | 86 | 		catch (IntegrationException e) {  | 
86 | 87 | 			if ( activationContext.getValidationModes().contains( ValidationMode.CALLBACK ) ) {  | 
@@ -112,7 +113,7 @@ public static void applyCallbackListeners(ValidatorFactory validatorFactory, Act  | 
112 | 113 | 		// de-activate not-null tracking at the core level when Bean Validation is present unless the user explicitly  | 
113 | 114 | 		// asks for it  | 
114 | 115 | 		if ( cfgService.getSettings().get( Environment.CHECK_NULLABILITY ) == null ) {  | 
115 |  | -			activationContext.getSessionFactory().getSettings().setCheckNullability( false );  | 
 | 116 | +			activationContext.getSessionFactory().getSessionFactoryOptions().setCheckNullability( false );  | 
116 | 117 | 		}  | 
117 | 118 | 
 
  | 
118 | 119 | 		final BeanValidationEventListener listener = new BeanValidationEventListener(  | 
@@ -151,7 +152,10 @@ private static void applyRelationalConstraints(ValidatorFactory factory, Activat  | 
151 | 152 | 				activationContext.getMetadata().getEntityBindings(),  | 
152 | 153 | 				cfgService.getSettings(),  | 
153 | 154 | 				activationContext.getServiceRegistry().getService( JdbcServices.class ).getDialect(),  | 
154 |  | -				new ClassLoaderAccessImpl( null, activationContext.getServiceRegistry().getService( ClassLoaderService.class ) )  | 
 | 155 | +				new ClassLoaderAccessImpl(  | 
 | 156 | +						null,  | 
 | 157 | +						activationContext.getServiceRegistry().getService( ClassLoaderService.class )  | 
 | 158 | +				)  | 
155 | 159 | 		);  | 
156 | 160 | 	}  | 
157 | 161 | 
 
  | 
@@ -303,16 +307,17 @@ private static void applySQLCheck(Column col, String checkConstraint) {  | 
303 | 307 | 		col.setCheckConstraint( checkConstraint );  | 
304 | 308 | 	}  | 
305 | 309 | 
 
  | 
 | 310 | +	@SuppressWarnings("unchecked")  | 
306 | 311 | 	private static boolean applyNotNull(Property property, ConstraintDescriptor<?> descriptor) {  | 
307 | 312 | 		boolean hasNotNull = false;  | 
308 | 313 | 		if ( NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) {  | 
309 | 314 | 			// single table inheritance should not be forced to null due to shared state  | 
310 | 315 | 			if ( !( property.getPersistentClass() instanceof SingleTableSubclass ) ) {  | 
311 | 316 | 				//composite should not add not-null on all columns  | 
312 | 317 | 				if ( !property.isComposite() ) {  | 
313 |  | -					final Iterator<Selectable> iter = property.getColumnIterator();  | 
314 |  | -					while ( iter.hasNext() ) {  | 
315 |  | -						final Selectable selectable = iter.next();  | 
 | 318 | +					final Iterator<Selectable> itr = property.getColumnIterator();  | 
 | 319 | +					while ( itr.hasNext() ) {  | 
 | 320 | +						final Selectable selectable = itr.next();  | 
316 | 321 | 						if ( Column.class.isInstance( selectable ) ) {  | 
317 | 322 | 							Column.class.cast( selectable ).setNullable( false );  | 
318 | 323 | 						}  | 
@@ -371,10 +376,8 @@ private static void applyLength(Property property, ConstraintDescriptor<?> descr  | 
371 | 376 | 	}  | 
372 | 377 | 
 
  | 
373 | 378 | 	/**  | 
374 |  | -	 * @param associatedClass  | 
375 |  | -	 * @param propertyName  | 
376 |  | -     * @return the property by path in a recursive way, including IdentifierProperty in the loop if propertyName is  | 
377 |  | -     * <code>null</code>.  If propertyName is <code>null</code> or empty, the IdentifierProperty is returned  | 
 | 379 | +	 * Locate the property by path in a recursive way, including IdentifierProperty in the loop if propertyName is  | 
 | 380 | +	 * {@code null}.  If propertyName is {@code null} or empty, the IdentifierProperty is returned  | 
378 | 381 | 	 */  | 
379 | 382 | 	private static Property findPropertyByName(PersistentClass associatedClass, String propertyName) {  | 
380 | 383 | 		Property property = null;  | 
@@ -434,30 +437,81 @@ private static Property findPropertyByName(PersistentClass associatedClass, Stri  | 
434 | 437 | 		return property;  | 
435 | 438 | 	}  | 
436 | 439 | 
 
  | 
437 |  | -	private static ValidatorFactory getValidatorFactory(Map<Object, Object> properties) {  | 
438 |  | -		ValidatorFactory factory = null;  | 
439 |  | -		if ( properties != null ) {  | 
440 |  | -			Object unsafeProperty = properties.get( FACTORY_PROPERTY );  | 
441 |  | -			if ( unsafeProperty != null ) {  | 
442 |  | -				try {  | 
443 |  | -					factory = ValidatorFactory.class.cast( unsafeProperty );  | 
444 |  | -				}  | 
445 |  | -				catch ( ClassCastException e ) {  | 
446 |  | -					throw new IntegrationException(  | 
447 |  | -							"Property " + FACTORY_PROPERTY  | 
448 |  | -									+ " should contain an object of type " + ValidatorFactory.class.getName()  | 
449 |  | -					);  | 
450 |  | -				}  | 
451 |  | -			}  | 
 | 440 | +	private static ValidatorFactory getValidatorFactory(ActivationContext activationContext) {  | 
 | 441 | +		// IMPL NOTE : We can either be provided a ValidatorFactory or make one.  We can be provided  | 
 | 442 | +		// a ValidatorFactory in 2 different ways.  So here we "get" a ValidatorFactory in the following order:  | 
 | 443 | +		//		1) Look into SessionFactoryOptions.getValidatorFactoryReference()  | 
 | 444 | +		//		2) Look into ConfigurationService  | 
 | 445 | +		//		3) build a new ValidatorFactory  | 
 | 446 | + | 
 | 447 | +		// 1 - look in SessionFactoryOptions.getValidatorFactoryReference()  | 
 | 448 | +		ValidatorFactory factory = resolveProvidedFactory( activationContext.getSessionFactory().getSessionFactoryOptions() );  | 
 | 449 | +		if ( factory != null ) {  | 
 | 450 | +			return factory;  | 
452 | 451 | 		}  | 
453 |  | -		if ( factory == null ) {  | 
454 |  | -			try {  | 
455 |  | -				factory = Validation.buildDefaultValidatorFactory();  | 
456 |  | -			}  | 
457 |  | -			catch ( Exception e ) {  | 
458 |  | -				throw new IntegrationException( "Unable to build the default ValidatorFactory", e );  | 
459 |  | -			}  | 
 | 452 | + | 
 | 453 | +		// 2 - look in ConfigurationService  | 
 | 454 | +		factory = resolveProvidedFactory( activationContext.getServiceRegistry().getService( ConfigurationService.class ) );  | 
 | 455 | +		if ( factory != null ) {  | 
 | 456 | +			return factory;  | 
 | 457 | +		}  | 
 | 458 | + | 
 | 459 | +		// 3 - build our own  | 
 | 460 | +		try {  | 
 | 461 | +			return Validation.buildDefaultValidatorFactory();  | 
 | 462 | +		}  | 
 | 463 | +		catch ( Exception e ) {  | 
 | 464 | +			throw new IntegrationException( "Unable to build the default ValidatorFactory", e );  | 
 | 465 | +		}  | 
 | 466 | +	}  | 
 | 467 | + | 
 | 468 | +	private static ValidatorFactory resolveProvidedFactory(SessionFactoryOptions options) {  | 
 | 469 | +		final Object validatorFactoryReference = options.getValidatorFactoryReference();  | 
 | 470 | + | 
 | 471 | +		if ( validatorFactoryReference == null ) {  | 
 | 472 | +			return null;  | 
 | 473 | +		}  | 
 | 474 | + | 
 | 475 | +		try {  | 
 | 476 | +			return ValidatorFactory.class.cast( validatorFactoryReference );  | 
 | 477 | +		}  | 
 | 478 | +		catch ( ClassCastException e ) {  | 
 | 479 | +			throw new IntegrationException(  | 
 | 480 | +					String.format(  | 
 | 481 | +							Locale.ENGLISH,  | 
 | 482 | +							"ValidatorFactory reference (provided via %s) was not castable to %s : %s",  | 
 | 483 | +							SessionFactoryOptions.class.getName(),  | 
 | 484 | +							ValidatorFactory.class.getName(),  | 
 | 485 | +							validatorFactoryReference.getClass().getName()  | 
 | 486 | +					)  | 
 | 487 | +			);  | 
460 | 488 | 		}  | 
461 |  | -		return factory;  | 
 | 489 | +	}  | 
 | 490 | + | 
 | 491 | +	@SuppressWarnings("unchecked")  | 
 | 492 | +	private static ValidatorFactory resolveProvidedFactory(ConfigurationService cfgService) {  | 
 | 493 | +		return cfgService.getSetting(  | 
 | 494 | +				FACTORY_PROPERTY,  | 
 | 495 | +				new ConfigurationService.Converter<ValidatorFactory>() {  | 
 | 496 | +					@Override  | 
 | 497 | +					public ValidatorFactory convert(Object value) {  | 
 | 498 | +						try {  | 
 | 499 | +							return ValidatorFactory.class.cast( value );  | 
 | 500 | +						}  | 
 | 501 | +						catch ( ClassCastException e ) {  | 
 | 502 | +							throw new IntegrationException(  | 
 | 503 | +									String.format(  | 
 | 504 | +											Locale.ENGLISH,  | 
 | 505 | +											"ValidatorFactory reference (provided via `%s` setting) was not castable to %s : %s",  | 
 | 506 | +											FACTORY_PROPERTY,  | 
 | 507 | +											ValidatorFactory.class.getName(),  | 
 | 508 | +											value.getClass().getName()  | 
 | 509 | +									)  | 
 | 510 | +							);  | 
 | 511 | +						}  | 
 | 512 | +					}  | 
 | 513 | +				},  | 
 | 514 | +				null  | 
 | 515 | +		);  | 
462 | 516 | 	}  | 
463 | 517 | }  | 
0 commit comments