Browse Source

Enforce JPA bootstrap failure for incomplete Hibernate Validator setup

Closes gh-30549
pull/30554/head
Juergen Hoeller 3 years ago
parent
commit
a45d438f05
  1. 1
      spring-orm/spring-orm.gradle
  2. 32
      spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java

1
spring-orm/spring-orm.gradle

@ -11,6 +11,7 @@ dependencies { @@ -11,6 +11,7 @@ dependencies {
optional("org.eclipse.persistence:org.eclipse.persistence.jpa")
optional("org.hibernate:hibernate-core-jakarta")
optional("jakarta.servlet:jakarta.servlet-api")
optional("jakarta.validation:jakarta.validation-api")
testImplementation(project(":spring-core-test"))
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-context")))

32
spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java

@ -31,6 +31,8 @@ import jakarta.persistence.PersistenceException; @@ -31,6 +31,8 @@ import jakarta.persistence.PersistenceException;
import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.ValidationMode;
import jakarta.persistence.spi.PersistenceUnitInfo;
import jakarta.validation.NoProviderFoundException;
import jakarta.validation.Validation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -48,6 +50,7 @@ import org.springframework.jdbc.datasource.lookup.DataSourceLookup; @@ -48,6 +50,7 @@ import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.jdbc.datasource.lookup.MapDataSourceLookup;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils;
@ -100,6 +103,9 @@ public class DefaultPersistenceUnitManager @@ -100,6 +103,9 @@ public class DefaultPersistenceUnitManager
public static final String ORIGINAL_DEFAULT_PERSISTENCE_UNIT_NAME = "default";
private static final boolean beanValidationPresent = ClassUtils.isPresent(
"jakarta.validation.Validation", DefaultPersistenceUnitManager.class.getClassLoader());
protected final Log logger = LogFactory.getLog(getClass());
private String[] persistenceXmlLocations = new String[] {DEFAULT_PERSISTENCE_XML_LOCATION};
@ -449,7 +455,7 @@ public class DefaultPersistenceUnitManager @@ -449,7 +455,7 @@ public class DefaultPersistenceUnitManager
pui.setPersistenceUnitRootUrl(determineDefaultPersistenceUnitRootUrl());
}
// Override DataSource and cache/validation mode
// Override DataSource and shared cache mode
if (pui.getJtaDataSource() == null && this.defaultJtaDataSource != null) {
pui.setJtaDataSource(this.defaultJtaDataSource);
}
@ -459,9 +465,16 @@ public class DefaultPersistenceUnitManager @@ -459,9 +465,16 @@ public class DefaultPersistenceUnitManager
if (this.sharedCacheMode != null) {
pui.setSharedCacheMode(this.sharedCacheMode);
}
// Override validation mode or pre-resolve provider detection
if (this.validationMode != null) {
pui.setValidationMode(this.validationMode);
}
else if (pui.getValidationMode() == ValidationMode.AUTO) {
pui.setValidationMode(
beanValidationPresent && BeanValidationDelegate.isValidationProviderPresent() ?
ValidationMode.CALLBACK : ValidationMode.NONE);
}
// Initialize persistence unit ClassLoader
if (this.loadTimeWeaver != null) {
@ -697,4 +710,21 @@ public class DefaultPersistenceUnitManager @@ -697,4 +710,21 @@ public class DefaultPersistenceUnitManager
return pui;
}
/**
* Inner class to avoid a hard dependency on the Bean Validation API at runtime.
*/
private static class BeanValidationDelegate {
public static boolean isValidationProviderPresent() {
try {
Validation.byDefaultProvider().configure();
return true;
}
catch (NoProviderFoundException ex) {
return false;
}
}
}
}

Loading…
Cancel
Save