HHH-9905 - JPA integration property "javax.persistence.validation.factory" not passed along to TypeSafeActivator
This commit is contained in:
parent
d50258f424
commit
c44afee6dc
|
@ -11,6 +11,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
@ -31,6 +32,7 @@ import org.hibernate.boot.internal.ClassLoaderAccessImpl;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.ClassLoaderAccess;
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
|
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
|
@ -77,10 +79,9 @@ class TypeSafeActivator {
|
||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
public static void activate(ActivationContext activationContext) {
|
public static void activate(ActivationContext activationContext) {
|
||||||
final ConfigurationService cfgService = activationContext.getServiceRegistry().getService( ConfigurationService.class );
|
|
||||||
final ValidatorFactory factory;
|
final ValidatorFactory factory;
|
||||||
try {
|
try {
|
||||||
factory = getValidatorFactory( cfgService.getSettings() );
|
factory = getValidatorFactory( activationContext );
|
||||||
}
|
}
|
||||||
catch (IntegrationException e) {
|
catch (IntegrationException e) {
|
||||||
if ( activationContext.getValidationModes().contains( ValidationMode.CALLBACK ) ) {
|
if ( activationContext.getValidationModes().contains( ValidationMode.CALLBACK ) ) {
|
||||||
|
@ -112,7 +113,7 @@ class TypeSafeActivator {
|
||||||
// de-activate not-null tracking at the core level when Bean Validation is present unless the user explicitly
|
// de-activate not-null tracking at the core level when Bean Validation is present unless the user explicitly
|
||||||
// asks for it
|
// asks for it
|
||||||
if ( cfgService.getSettings().get( Environment.CHECK_NULLABILITY ) == null ) {
|
if ( cfgService.getSettings().get( Environment.CHECK_NULLABILITY ) == null ) {
|
||||||
activationContext.getSessionFactory().getSettings().setCheckNullability( false );
|
activationContext.getSessionFactory().getSessionFactoryOptions().setCheckNullability( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
final BeanValidationEventListener listener = new BeanValidationEventListener(
|
final BeanValidationEventListener listener = new BeanValidationEventListener(
|
||||||
|
@ -151,7 +152,10 @@ class TypeSafeActivator {
|
||||||
activationContext.getMetadata().getEntityBindings(),
|
activationContext.getMetadata().getEntityBindings(),
|
||||||
cfgService.getSettings(),
|
cfgService.getSettings(),
|
||||||
activationContext.getServiceRegistry().getService( JdbcServices.class ).getDialect(),
|
activationContext.getServiceRegistry().getService( JdbcServices.class ).getDialect(),
|
||||||
new ClassLoaderAccessImpl( null, activationContext.getServiceRegistry().getService( ClassLoaderService.class ) )
|
new ClassLoaderAccessImpl(
|
||||||
|
null,
|
||||||
|
activationContext.getServiceRegistry().getService( ClassLoaderService.class )
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,6 +307,7 @@ class TypeSafeActivator {
|
||||||
col.setCheckConstraint( checkConstraint );
|
col.setCheckConstraint( checkConstraint );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private static boolean applyNotNull(Property property, ConstraintDescriptor<?> descriptor) {
|
private static boolean applyNotNull(Property property, ConstraintDescriptor<?> descriptor) {
|
||||||
boolean hasNotNull = false;
|
boolean hasNotNull = false;
|
||||||
if ( NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) {
|
if ( NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) {
|
||||||
|
@ -310,9 +315,9 @@ class TypeSafeActivator {
|
||||||
if ( !( property.getPersistentClass() instanceof SingleTableSubclass ) ) {
|
if ( !( property.getPersistentClass() instanceof SingleTableSubclass ) ) {
|
||||||
//composite should not add not-null on all columns
|
//composite should not add not-null on all columns
|
||||||
if ( !property.isComposite() ) {
|
if ( !property.isComposite() ) {
|
||||||
final Iterator<Selectable> iter = property.getColumnIterator();
|
final Iterator<Selectable> itr = property.getColumnIterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( itr.hasNext() ) {
|
||||||
final Selectable selectable = iter.next();
|
final Selectable selectable = itr.next();
|
||||||
if ( Column.class.isInstance( selectable ) ) {
|
if ( Column.class.isInstance( selectable ) ) {
|
||||||
Column.class.cast( selectable ).setNullable( false );
|
Column.class.cast( selectable ).setNullable( false );
|
||||||
}
|
}
|
||||||
|
@ -371,10 +376,8 @@ class TypeSafeActivator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param associatedClass
|
* Locate the property by path in a recursive way, including IdentifierProperty in the loop if propertyName is
|
||||||
* @param propertyName
|
* {@code null}. If propertyName is {@code null} or empty, the IdentifierProperty is returned
|
||||||
* @return the property by path in a recursive way, including IdentifierProperty in the loop if propertyName is
|
|
||||||
* <code>null</code>. If propertyName is <code>null</code> or empty, the IdentifierProperty is returned
|
|
||||||
*/
|
*/
|
||||||
private static Property findPropertyByName(PersistentClass associatedClass, String propertyName) {
|
private static Property findPropertyByName(PersistentClass associatedClass, String propertyName) {
|
||||||
Property property = null;
|
Property property = null;
|
||||||
|
@ -434,30 +437,81 @@ class TypeSafeActivator {
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ValidatorFactory getValidatorFactory(Map<Object, Object> properties) {
|
private static ValidatorFactory getValidatorFactory(ActivationContext activationContext) {
|
||||||
ValidatorFactory factory = null;
|
// IMPL NOTE : We can either be provided a ValidatorFactory or make one. We can be provided
|
||||||
if ( properties != null ) {
|
// a ValidatorFactory in 2 different ways. So here we "get" a ValidatorFactory in the following order:
|
||||||
Object unsafeProperty = properties.get( FACTORY_PROPERTY );
|
// 1) Look into SessionFactoryOptions.getValidatorFactoryReference()
|
||||||
if ( unsafeProperty != null ) {
|
// 2) Look into ConfigurationService
|
||||||
try {
|
// 3) build a new ValidatorFactory
|
||||||
factory = ValidatorFactory.class.cast( unsafeProperty );
|
|
||||||
}
|
// 1 - look in SessionFactoryOptions.getValidatorFactoryReference()
|
||||||
catch ( ClassCastException e ) {
|
ValidatorFactory factory = resolveProvidedFactory( activationContext.getSessionFactory().getSessionFactoryOptions() );
|
||||||
throw new IntegrationException(
|
if ( factory != null ) {
|
||||||
"Property " + FACTORY_PROPERTY
|
return factory;
|
||||||
+ " should contain an object of type " + ValidatorFactory.class.getName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ( factory == null ) {
|
|
||||||
try {
|
// 2 - look in ConfigurationService
|
||||||
factory = Validation.buildDefaultValidatorFactory();
|
factory = resolveProvidedFactory( activationContext.getServiceRegistry().getService( ConfigurationService.class ) );
|
||||||
}
|
if ( factory != null ) {
|
||||||
catch ( Exception e ) {
|
return factory;
|
||||||
throw new IntegrationException( "Unable to build the default ValidatorFactory", e );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return factory;
|
|
||||||
|
// 3 - build our own
|
||||||
|
try {
|
||||||
|
return Validation.buildDefaultValidatorFactory();
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
throw new IntegrationException( "Unable to build the default ValidatorFactory", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ValidatorFactory resolveProvidedFactory(SessionFactoryOptions options) {
|
||||||
|
final Object validatorFactoryReference = options.getValidatorFactoryReference();
|
||||||
|
|
||||||
|
if ( validatorFactoryReference == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return ValidatorFactory.class.cast( validatorFactoryReference );
|
||||||
|
}
|
||||||
|
catch ( ClassCastException e ) {
|
||||||
|
throw new IntegrationException(
|
||||||
|
String.format(
|
||||||
|
Locale.ENGLISH,
|
||||||
|
"ValidatorFactory reference (provided via %s) was not castable to %s : %s",
|
||||||
|
SessionFactoryOptions.class.getName(),
|
||||||
|
ValidatorFactory.class.getName(),
|
||||||
|
validatorFactoryReference.getClass().getName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static ValidatorFactory resolveProvidedFactory(ConfigurationService cfgService) {
|
||||||
|
return cfgService.getSetting(
|
||||||
|
FACTORY_PROPERTY,
|
||||||
|
new ConfigurationService.Converter<ValidatorFactory>() {
|
||||||
|
@Override
|
||||||
|
public ValidatorFactory convert(Object value) {
|
||||||
|
try {
|
||||||
|
return ValidatorFactory.class.cast( value );
|
||||||
|
}
|
||||||
|
catch ( ClassCastException e ) {
|
||||||
|
throw new IntegrationException(
|
||||||
|
String.format(
|
||||||
|
Locale.ENGLISH,
|
||||||
|
"ValidatorFactory reference (provided via `%s` setting) was not castable to %s : %s",
|
||||||
|
FACTORY_PROPERTY,
|
||||||
|
ValidatorFactory.class.getName(),
|
||||||
|
value.getClass().getName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue