我正在我的项目中执行服务器端验证。我在这个项目中使用 spring 和 hibernate。 我已经使用 hibernate 约束在 POJO 级别编写了验证。 这里的要求是,在保存数据时,应该触发验证,这是我已经编写的,并且我无法删除验证,而且我无法更改当前场景的结构。 然而,有一个处理程序需要在不触发验证的情况下保存数据。所以我必须在此处理程序中暂时禁用验证。
任何帮助将不胜感激。!!! 预先感谢。
Hibernate 中没有内置的方法来禁用注释。 在这篇文章中:在运行时动态禁用休眠验证注释,提到了一些通过扩展现有验证器并使用 Validator.validateValue 来创建自定义验证器的方法。 希望这有帮助!
我的测试解决方案
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);
}
}