Tanmay Matondkar
Tanmay Matondkar

Reputation: 93

Skip hibernate validation temporarily

I am performing serverside validation in my project. I am using spring and hibernate for this project. I have written validations at POJO level using hibernate constraints. The requirement here is that on saving the data the validation should be triggered, which i have already written And i cannot remove the validations plus i cannot change the structure of current scenario. However, there is one handler where data needs to be saved without triggering the validations. So I have to disable validations temporarily in this handler.

Any help would be appreciated.!!!! Thanks in advance.

Upvotes: 2

Views: 2547

Answers (2)

My solution for tests

import org.hibernate.cfg.beanvalidation.BeanValidationEventListener;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PreDeleteEventListener;
import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.event.spi.PreUpdateEventListener;
import org.hibernate.service.ServiceRegistry;

import javax.persistence.EntityManagerFactory;
import java.util.ArrayList;
import java.util.List;

public class BeanValidation {
    private final static List<PreInsertEventListener> preInsertEventListeners = new ArrayList<>();
    private final static List<PreUpdateEventListener> preUpdateEventListeners = new ArrayList<>();
    private final static List<PreDeleteEventListener> preDeleteEventListeners = new ArrayList<>();

    public static void disable(EntityManagerFactory entityManagerFactory) {
        EventListenerRegistry listenerRegistry = getEventListenerRegistry(entityManagerFactory);
        saveEventsAndRemoveBeanValidationListener(listenerRegistry, preInsertEventListeners, EventType.PRE_INSERT);
        saveEventsAndRemoveBeanValidationListener(listenerRegistry, preUpdateEventListeners, EventType.PRE_UPDATE);
        saveEventsAndRemoveBeanValidationListener(listenerRegistry, preDeleteEventListeners, EventType.PRE_DELETE);
    }

    public static void enable(EntityManagerFactory entityManagerFactory) {
        EventListenerRegistry listenerRegistry = getEventListenerRegistry(entityManagerFactory);
        restoreEvents(listenerRegistry, preInsertEventListeners, EventType.PRE_INSERT);
        restoreEvents(listenerRegistry, preUpdateEventListeners, EventType.PRE_UPDATE);
        restoreEvents(listenerRegistry, preDeleteEventListeners, EventType.PRE_DELETE);
    }

    private static EventListenerRegistry getEventListenerRegistry(EntityManagerFactory entityManagerFactory) {
        SessionFactoryImplementor sessionFactory = entityManagerFactory.unwrap(SessionFactoryImplementor.class);
        ServiceRegistry serviceRegistry = sessionFactory.getServiceRegistry();
        return serviceRegistry.getService(EventListenerRegistry.class);
    }

    private static <T> void saveEventsAndRemoveBeanValidationListener(EventListenerRegistry listenerRegistry,
                                                                      List<T> list, EventType<T> eventType) {
        list.clear();
        EventListenerGroup<T> eventListenerGroup = listenerRegistry.getEventListenerGroup(eventType);
        eventListenerGroup.fireEventOnEachListener("", (listener, s) -> {
            list.add(listener);
    });
    eventListenerGroup.clearListeners();
    list.stream()
            .filter(l -> !(l instanceof BeanValidationEventListener))
            .forEach(eventListenerGroup::appendListener);
}

private static <T> void restoreEvents(EventListenerRegistry listenerRegistry, List<T> list, EventType<T> eventType) {
    EventListenerGroup<T> eventListenerGroup = 

listenerRegistry.getEventListenerGroup(eventType);
        eventListenerGroup.clearListeners();
            list.forEach(eventListenerGroup::appendListener);
        }
}

Upvotes: 0

Rohit Gulati
Rohit Gulati

Reputation: 542

There is no inbuilt way to disable annotation in Hibernate. In the post : Disabling hibernate validation annotations dynamically at runtime, there are some ways mentioned to create your custom validator by extending the existing one and using Validator.validateValue. Hope this helps !

Upvotes: 3

Related Questions