Bean Validation: How can I manually create a ConstraintViolation?

javax validation custom validator
javax.validation.constraints java 8
javax validation custom message
javax validation date
contains constraint annotation, but does not contain a message parameter
notnull not working spring-boot
bean validation composition
java validation library

I have a specific scenario where I can only check for violation conditions manually, at a later point in the flow.

What I want to do is throw a ConstraintViolationException, and provide a "real" ConstraintViolation object to it (when I catch the exception up the stack, I use the #{validatedValue} and violation.getPropertyPath() parameters).

How can I create a ConstraintViolation myself without having the framework do it for me via annotations (I use Hibernate Validator)?

Code example:

List<String> columnsListForSorting = new ArrayList<String>(service.getColumnsList(domain));
Collections.sort(columnsListForSorting);

String firstFieldToSortBy = this.getTranslatedFieldName(domain.getClass().getCanonicalName(), sortingInfo.getSortedColumn());
if (!columnsListForSorting.contains(firstFieldToSortBy)){
    throw new ConstraintViolationException(<what here?...>);
}

Thanks.

In my opinion, the simplest way would be to mock your service into throwing the constraint violation in your test. You can do it manually by extending the class for example, or you can use a mocking framework such as mockito. I prefer mocking frameworks because they simplify things a lot as you neither have to create and maintain additional classes nor have to deal with injecting them in your objects under test.

Taking mockito as a starting point you'd probably write something similar to:

import org.hibernate.exception.ConstraintViolationException;
import org.mockito.InjectMocks;
import org.mockito.Mock;

import static org.mockito.Mockito.when;


public class MyTest {
    @Mock /* service mock */
    private MyService myService;

    @InjectMocks /* inject the mocks in the object under test */
    private ServiceCaller serviceCaller;

    @Test
    public void shouldHandleConstraintViolation() {
        // make the mock throw the exception when called
        when(myService.someMethod(...)).thenThrow(new ConstraintViolationException(...))

        // get the operation result
        MyResult result = serviceCaller.doSomeStuffWhichInvokesTheServiceMethodThrowingConstraintViolation();

        // verify all went according to plan
        assertWhatever(result);
    }
}

Chapter 2. Validation step by step, In fact, none of the default constraints defined by Bean Validation can be In Example 2.3, “Class level constraint” we add the property passengers to the Otherwise a ConstraintViolation instance is added for each violated constraint. For older Java versions, the JSR 223 RI can be added manually to the class path. This makes bean validation a very valuable tool. Specially when programming an API. For example, you can use it to validate REST API calls. It can also be used to enforce certain data rules inside your application. In this tutorial, we will discuss how to use Java bean validation in a Spring boot environment.

A couple of things here:

  1. ConstraintViolation is an interface, so you could just implement your own version

  2. Hibernate Validator uses its own internal implementation of this interface - org.hibernate.validator.internal.engine.ConstraintViolationImpl. It is a public class, but since it is in an internal package you are not encouraged to use it directly. However, you might get an idea what is needed to implement ConstraintViolation.

Chapter 3. Creating custom constraints, To create a custom constraint, the following three steps are required: an attribute payload that can be used by clients of the Bean Validation API to assign path creation could look like Example 3.5, “Adding new ConstraintViolation with  As of version 1.1, Bean Validation constraints can also be applied to the parameters and return values of methods of arbitrary Java types. Thus the Bean Validation API can be used to describe and validate the contract (comprising pre- and postconditions) applying to a given method ("Programming by Contract", PbC).

One more reason why I don't like Hibernate Validator that particular. They make it really hard to create a simple violation programmatically, when it should be dead simple. I do have test code where I need to create a violation to feed to my mocked subsystem.

Anyway, short of rolling your own implementation of a violation contraint - here is what I do to create a violation for a field:

private static final String MESSAGE_TEMPLATE = "{messageTemplate}";
private static final String MESSAGE = "message";

public static <T, A extends Annotation> ConstraintViolation<T> forField(
  final T rootBean, 
  final Class<T> clazz,
  final Class<A> annotationClazz,
  final Object leafBean, 
  final String field, 
  final Object offendingValue) {

  ConstraintViolation<T> violation = null;
  try {
    Field member = clazz.getDeclaredField(field);
    A annotation = member.getAnnotation(annotationClazz);
    ConstraintDescriptor<A> descriptor = new ConstraintDescriptorImpl<>(
      new ConstraintHelper(), 
      member, 
      annotation, 
      ElementType.FIELD);
    Path p = PathImpl.createPathFromString(field);
    violation = ConstraintViolationImpl.forBeanValidation(
      MESSAGE_TEMPLATE, 
      MESSAGE, 
      clazz, 
      rootBean, 
      leafBean,
      offendingValue, 
      p, 
      descriptor, 
      ElementType.FIELD);
  } catch (NoSuchFieldException ignore) {}
  return violation;

}

HTH

Java Code Examples javax.validation.ConstraintViolation, You can vote up the examples you like and your votes will be used in our system to generate more good examples. Example 1. Project: cmc-claim-store File:  JSR 380 is a specification of the Java API for bean validation, part of Jakarta EE and JavaSE, which ensures that the properties of a bean meet specific criteria, using annotations such as @NotNull, @Min, and @Max. This version requires Java 8 or higher, and takes advantage of new features added in Java 8 such as type annotations, and supports new types like Optional and LocalDate.

Why not inject the Validator in your test and create an object triggering the validation errors you want?

Set<ConstraintViolation<T>> res = validator.validate(object);

Method Constraints with Bean Validation 2.0, An introduction to method constraints using Bean Validation 2.0. Also, we'll have a look at how to validate the constraints manually and automatically using Spring Validator. We simply have to add annotations to each parameter as required: ? ConstraintViolationException, if a constraint is violated. Fortunately, I have good news for you. Creating a custom validation annotation is pretty easy. In this post, you will learn how to create a custom constraint annotation and a corresponding validator class. You will also see how to use Spring beans inside a custom validator. Let’s just right into it.

I encountered this issue several times already and came up with this little solution. It is based on the validateValue method of the Validator and using a helper-validator in the test class, which is used to generate in a one liner a Set<ConstraintViolation<T>> object.

suppose you are testing a class that internally uses a Validator, mocked in our test, on an object "Data data" which has Bean Validation annotations, for example the field "sessionId" is annotated with @NotNull.

Your test class would then have at least these two members:

@Mock
private Validator validator;

private Validator violationCreatorValidator;

@Before
public void setup() {
     MockitoAnnotations.initMocks(this);
     violationsGenerator.Validation.buildDefaultValidatorFactory().getValidator();
}

And then in the test case:

when(validator.validate(data))
.thenReturn(violationsGenerator.validateValue(Data.class, "sessionId", null));

Thats it. No need to a implement the ConstraintViolation interface or call the monstrous ConstraintViolationImpl.forBeanValidation. Let the Validator do the job for you.

How to Invoke JSR 303 Bean Validation Programmatically, These days I've found a nice tutorial on bean validation, that shows - among other things - how to invoke Hibernate Validator manually. getValidator(); Set<​ConstraintViolation<AdditionBean>> errors It takes three lines of code to invoke the validator: get a ValidatorFactory, have it build you a validator  Another built-in constraint in Bean Validation 2.0 is @Email, which can validate that the Astronaut bean includes a correctly formatted email address. The annotation constrains the emailAddress field. The astronaut needs to be between 18 and 100 years old. Bean validation allows you to specify multiple constraints on a single field.

All You Need To Know About Bean Validation With Spring Boot, It's not necessary to add the version number since the Spring Very basically, Bean Validation works by defining constraints to the fields of a a failed validation will trigger a ConstraintViolationException instead of a In this case, we can just create a Validator by hand and invoke it to trigger a validation:. The custom constraint annotations (JSR 303/349/380) can be created as specified by the JavaBean validation specification (check out example here).. In spring if we register LocalValidatorFactoryBean to bootstrap javax.validation.ValidatorFactory then custom ConstraintValidator classes are loaded as Spring Bean.

How to add a new constraint to Hibernate Validator in a few simple , All the Hibernate Validator users can benefit from these constraints. They are In order to do this, first a new constraint annotation should be created. In our Set<​ConstraintViolation<Foo>> violations = validator.validate( foo );  While using the Validator manually might be useful for some advanced usage, if you simply want to validate the parameters or the return value or your REST end point, you can annotate it directly, either with constraints (@NotNull, @Digits … ​) or with @Valid (which will cascade the validation to the bean).

Validating constraints for JavaBeans in Java microservices, Validation can be performed manually or with integration with other Bean validation provides both built-in constraints and the ability to create custom Replace OpenLiberty with anything else to note that a constraint violation is returned. Many frameworks, however, offer integration with Bean Validation out of the box, e.g. JPA and JSF. In this case it is enough to annotate your POJOs with constraint annotations. Validation will occur automatically at the appropriate life cycle phase of the used technology. Refer to the reference guide for more information.

Comments
  • What is your test code so far?
  • Edit your question, add the snippet and format it with the "code" button, it makes it easier to read :)
  • Thanks, original question has been updated.
  • Based on your snippet, why not throw and catch a custom exception to better express what is happening throw new MissingFilterField(firstFieldToSortBy)?
  • Because up the stack, a ConstraintViolation exception is caught that already translates the exception to the expected error return value for the customer. But I get what you're saying. Perhaps I should just create a new exception handling scenario.
  • Thank you for the answer. I think I should have made it clear: this is not for testing purposes, it's production code.
  • Then unless you can not alter the code that is catching the exception, I see no point in throwing a constraint violation. You're way better of throwing a dedicated exception which makes it easier to understand what you're trying to achieve
  • What I'm trying to say is that I don't see many reasons to throw a NullPointerException if my number should be > 5 but in fact it is 1, if you catch my drift
  • Thank you for the recommendation. I eventually decided to implement my own custom exception as you suggested. I'm still using the same ValidationMessages from hibernate validator, only I parse it myself. That way I can reuse the same error text from both exceptions.
  • Great! You can post the above as an answer and accept it as the correct one after a few days, it does not necessarily have to be someone else's. Cheers
  • ConstraintViolationImpl.forBeanValidation() will only work starting from Hibernate Validator 5.x
  • Can you please explain how violationsGenerator is implemented?