Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,24 @@ public class BeanValidationEventListener
public BeanValidationEventListener(
ValidatorFactory factory, Map<String, Object> settings, ClassLoaderService classLoaderService) {
traversableResolver = new HibernateTraversableResolver();
validator = factory.usingContext()
.traversableResolver( traversableResolver )
.getValidator();
validator =
factory.usingContext()
.traversableResolver( traversableResolver )
.getValidator();
groupsPerOperation = GroupsPerOperation.from( settings, new ClassLoaderAccessImpl( classLoaderService ) );
}

@Override
public void sessionFactoryCreated(SessionFactory factory) {
SessionFactoryImplementor implementor = factory.unwrap( SessionFactoryImplementor.class );
implementor
.getMappingMetamodel()
var implementor = factory.unwrap( SessionFactoryImplementor.class );
implementor.getMappingMetamodel()
.forEachEntityDescriptor( entityPersister -> traversableResolver.addPersister( entityPersister, implementor ) );
}

public boolean onPreInsert(PreInsertEvent event) {
validate(
event.getEntity(),
event.getPersister(),
event.getFactory(),
GroupsPerOperation.Operation.INSERT
);
return false;
Expand All @@ -84,7 +83,6 @@ public boolean onPreUpdate(PreUpdateEvent event) {
validate(
event.getEntity(),
event.getPersister(),
event.getFactory(),
GroupsPerOperation.Operation.UPDATE
);
return false;
Expand All @@ -94,7 +92,6 @@ public boolean onPreDelete(PreDeleteEvent event) {
validate(
event.getEntity(),
event.getPersister(),
event.getFactory(),
GroupsPerOperation.Operation.DELETE
);
return false;
Expand All @@ -105,7 +102,6 @@ public boolean onPreUpsert(PreUpsertEvent event) {
validate(
event.getEntity(),
event.getPersister(),
event.getFactory(),
GroupsPerOperation.Operation.UPSERT
);
return false;
Expand All @@ -117,54 +113,52 @@ public void onPreUpdateCollection(PreCollectionUpdateEvent event) {
validate(
entity,
event.getSession().getEntityPersister( event.getAffectedOwnerEntityName(), entity ),
event.getFactory(),
GroupsPerOperation.Operation.UPDATE
);
}

private <T> void validate(
T object,
EntityPersister persister,
SessionFactoryImplementor sessionFactory,
GroupsPerOperation.Operation operation) {
if ( object == null || persister.getRepresentationStrategy().getMode() != RepresentationMode.POJO ) {
return;
}
final Class<?>[] groups = groupsPerOperation.get( operation );
if ( groups.length > 0 ) {
final Set<ConstraintViolation<T>> constraintViolations = validator.validate( object, groups );
if ( !constraintViolations.isEmpty() ) {
final Set<ConstraintViolation<?>> propagatedViolations = setOfSize( constraintViolations.size() );
final Set<String> classNames = new HashSet<>();
for ( ConstraintViolation<?> violation : constraintViolations ) {
LOG.trace( violation );
propagatedViolations.add( violation );
classNames.add( violation.getLeafBean().getClass().getName() );
}
final StringBuilder builder = new StringBuilder();
builder.append( "Validation failed for classes " );
builder.append( classNames );
builder.append( " during " );
builder.append( operation.getName() );
builder.append( " time for groups " );
builder.append( toString( groups ) );
builder.append( "\nList of constraint violations:[\n" );
for ( ConstraintViolation<?> violation : constraintViolations ) {
builder.append( "\t" ).append( violation.toString() ).append( "\n" );
if ( object != null
&& persister.getRepresentationStrategy().getMode() == RepresentationMode.POJO ) {
final Class<?>[] groups = groupsPerOperation.get( operation );
if ( groups.length > 0 ) {
final var constraintViolations = validator.validate( object, groups );
if ( !constraintViolations.isEmpty() ) {
final Set<ConstraintViolation<?>> propagatedViolations = setOfSize( constraintViolations.size() );
final Set<String> classNames = new HashSet<>();
for ( var violation : constraintViolations ) {
LOG.trace( violation );
propagatedViolations.add( violation );
classNames.add( violation.getLeafBean().getClass().getName() );
}
final var builder =
new StringBuilder()
.append( "Validation failed for classes " )
.append( classNames )
.append( " during " )
.append( operation.getName() )
.append( " time for groups " )
.append( toString( groups ) )
.append( "\nList of constraint violations:[\n" );
for ( var violation : constraintViolations ) {
builder.append( "\t" ).append( violation.toString() ).append( "\n" );
}
builder.append( "]" );
throw new ConstraintViolationException( builder.toString(), propagatedViolations );
}
builder.append( "]" );

throw new ConstraintViolationException( builder.toString(), propagatedViolations );
}
}
}

private String toString(Class<?>[] groups) {
final StringBuilder toString = new StringBuilder( "[" );
for ( Class<?> group : groups ) {
toString.append( group.getName() ).append( ", " );
final var string = new StringBuilder( "[" );
for ( var group : groups ) {
string.append( group.getName() ).append( ", " );
}
toString.append( "]" );
return toString.toString();
string.append( "]" );
return string.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;

/**
Expand Down Expand Up @@ -48,9 +47,12 @@ public class BeanValidationIntegrator implements Integrator {
public static void validateFactory(Object object) {
try {
// this direct usage of ClassLoader should be fine since the classes exist in the same jar
final Class<?> activatorClass = BeanValidationIntegrator.class.getClassLoader().loadClass( ACTIVATOR_CLASS_NAME );
final var activatorClass =
BeanValidationIntegrator.class.getClassLoader()
.loadClass( ACTIVATOR_CLASS_NAME );
try {
final Method validateMethod = activatorClass.getMethod( VALIDATE_SUPPLIED_FACTORY_METHOD_NAME, Object.class );
final var validateMethod =
activatorClass.getMethod( VALIDATE_SUPPLIED_FACTORY_METHOD_NAME, Object.class );
try {
validateMethod.invoke( null, object );
}
Expand Down Expand Up @@ -84,14 +86,14 @@ public void integrate(
Metadata metadata,
BootstrapContext bootstrapContext,
SessionFactoryImplementor sessionFactory) {
final ServiceRegistryImplementor serviceRegistry = sessionFactory.getServiceRegistry();
final ConfigurationService cfgService = serviceRegistry.requireService( ConfigurationService.class );
// IMPL NOTE : see the comments on ActivationContext.getValidationModes() as to why this is multi-valued...
final var serviceRegistry = sessionFactory.getServiceRegistry();
final var cfgService = serviceRegistry.requireService( ConfigurationService.class );
// IMPL NOTE: see the comments on ActivationContext.getValidationModes() as to why this is multi-valued...
Object modeSetting = cfgService.getSettings().get( JAKARTA_MODE_PROPERTY );
if ( modeSetting == null ) {
modeSetting = cfgService.getSettings().get( MODE_PROPERTY );
}
final Set<ValidationMode> modes = ValidationMode.getModes( modeSetting );
final var modes = ValidationMode.getModes( modeSetting );
if ( modes.size() > 1 ) {
LOG.multipleValidationModes( ValidationMode.loggable( modes ) );
}
Expand All @@ -100,8 +102,7 @@ public void integrate(
return;
}

final ClassLoaderService classLoaderService = serviceRegistry.requireService( ClassLoaderService.class );

final var classLoaderService = serviceRegistry.requireService( ClassLoaderService.class );
// see if the Bean Validation API is available on the classpath
if ( isBeanValidationApiAvailable( classLoaderService ) ) {
// and if so, call out to the TypeSafeActivator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public class HibernateTraversableResolver implements TraversableResolver {
private final Map<Class<?>, Set<String>> associationsPerEntityClass = new HashMap<>();

public void addPersister(EntityPersister persister, SessionFactoryImplementor factory) {
Class<?> javaTypeClass = persister.getEntityMappingType().getMappedJavaType().getJavaTypeClass();
Set<String> associations = new HashSet<>();
final var javaTypeClass = persister.getEntityMappingType().getMappedJavaType().getJavaTypeClass();
final Set<String> associations = new HashSet<>();
addAssociationsToTheSetForAllProperties( persister.getPropertyNames(), persister.getPropertyTypes(), "", factory, associations );
associationsPerEntityClass.put( javaTypeClass, associations );
}
Expand Down Expand Up @@ -69,8 +69,8 @@ else if ( type instanceof ComponentType componentType ) {
}

private String getStringBasedPath(Path.Node traversableProperty, Path pathToTraversableObject) {
final StringBuilder path = new StringBuilder( );
for ( Path.Node node : pathToTraversableObject ) {
final var path = new StringBuilder( );
for ( var node : pathToTraversableObject ) {
if (node.getName() != null) {
path.append( node.getName() ).append( '.' );
}
Expand Down Expand Up @@ -99,10 +99,8 @@ public boolean isCascadable(Object traversableObject,
Class<?> rootBeanType,
Path pathToTraversableObject,
ElementType elementType) {
Set<String> associations = associationsPerEntityClass.get( rootBeanType);
if ( associations == null ) {
return false;
}
return !associations.contains( getStringBasedPath( traversableProperty, pathToTraversableObject ) );
final var associations = associationsPerEntityClass.get( rootBeanType);
return associations != null
&& !associations.contains( getStringBasedPath( traversableProperty, pathToTraversableObject ) );
}
}
Loading