Skip to content

Commit

Permalink
Fix validation for dynamic entities on the server
Browse files Browse the repository at this point in the history
Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
  • Loading branch information
lukasj committed Jun 27, 2022
1 parent 9afabf2 commit d230388
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 101 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
import jakarta.validation.ConstraintViolation;

import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.dynamic.DynamicType;
import org.eclipse.persistence.internal.jpa.config.metadata.ReflectiveDynamicClassLoader;
import org.eclipse.persistence.jpa.dynamic.JPADynamicHelper;
import org.eclipse.persistence.testing.framework.TestSuite;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.junit.Assert;

Expand Down Expand Up @@ -61,12 +61,17 @@ public static Test suite() {
* 4. Assert - The validation exception is due to invalid value given by us.
*/
public void testPersistDynamicEntityWithInvalidData() {
// Create an entity manager factory with a dynamic class loader.
DynamicClassLoader dcl = new ReflectiveDynamicClassLoader(Thread.currentThread().getContextClassLoader());
Map<String,Object> properties = new HashMap<>(getPersistenceProperties());
properties.put(PersistenceUnitProperties.CLASSLOADER, dcl);
// properties.put(PersistenceUnitProperties.BEAN_VALIDATION_NO_OPTIMISATION, "true");
EntityManager em = createEntityManager("beanvalidation-dynamic", properties);
EntityManager em;
if (isOnServer()) {
em = createEntityManager();
} else {
// Create an entity manager factory with a dynamic class loader.
DynamicClassLoader dcl = new ReflectiveDynamicClassLoader(Thread.currentThread().getContextClassLoader());
Map<String, Object> properties = new HashMap<>(getPersistenceProperties());
properties.put(PersistenceUnitProperties.CLASSLOADER, dcl);
// properties.put(PersistenceUnitProperties.BEAN_VALIDATION_NO_OPTIMISATION, "true");
em = createEntityManager("beanvalidation-dynamic", properties);
}
EntityManagerFactory entityManagerFactory = em.getEntityManagerFactory();

// Create types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,9 @@

package org.eclipse.persistence.internal.jpa.deployment;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Map;

import jakarta.validation.Configuration;
import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
Expand All @@ -31,6 +27,11 @@
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.AbstractSession;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Map;

/**
* Responsible for intialializing Bean Validation. The only expected instance of this interface is the inner class.
* @author Mitesh Meswani
Expand All @@ -46,7 +47,7 @@ public BeanValidationInitializationHelperImpl() {
@Override
public void bootstrapBeanValidation(Map puProperties, AbstractSession session, ClassLoader appClassLoader) {

ValidatorFactory validatorFactory = getValidatorFactory(puProperties);
ValidatorFactory validatorFactory = getValidatorFactory(puProperties, appClassLoader);

//Check user/environment has specified the validator factory
if (validatorFactory != null) {
Expand Down Expand Up @@ -75,13 +76,36 @@ public void bootstrapBeanValidation(Map puProperties, AbstractSession session, C
/**
* INTERNAL:
* @param puProperties merged properties for this persitence unit
* @param appClassLoader application class loader (can be ie DynamicClassLoader, or its subclass,
* with the knowledge about Virtual/Dynamic Entities)
* @return ValidatorFactory instance to be used for this persistence unit.
*/
private ValidatorFactory getValidatorFactory(Map puProperties) {
private ValidatorFactory getValidatorFactory(Map puProperties, final ClassLoader appClassLoader) {
ValidatorFactory validatorFactory = (ValidatorFactory)puProperties.get(PersistenceUnitProperties.VALIDATOR_FACTORY);

if (validatorFactory == null) {
validatorFactory = Validation.buildDefaultValidatorFactory();
Configuration<?> conf = Validation.byDefaultProvider().configure();
if (appClassLoader != null) {
try {
Configuration<?> finalConf = conf;
// set external classloader for hibernate-validator to let it find dynamic (virtual) entities
// without having compile-time dependency on it; in the other words, we can't do:
// Validation.byProvider( HibernateValidator.class )
// .configure()
// .externalClassLoader( classLoader )
// .buildValidatorFactory()
conf = PrivilegedAccessHelper.callDoPrivilegedWithThrowable(() -> {
Method m = PrivilegedAccessHelper.getMethod(finalConf.getClass(),
"externalClassLoader", new Class[]{ClassLoader.class},
false);
return (Configuration<?>) m.invoke(finalConf, appClassLoader);
}
);
} catch (Throwable t) {
// not hibernate-validator, so ignore
}
}
validatorFactory = conf.buildValidatorFactory();
}
return validatorFactory;
}
Expand Down

0 comments on commit d230388

Please sign in to comment.