diff --git a/javaxval/pom.xml b/javaxval/pom.xml
index 6a83a25f01..a05ee43aaf 100644
--- a/javaxval/pom.xml
+++ b/javaxval/pom.xml
@@ -6,10 +6,11 @@
0.1-SNAPSHOT
- 2.0.0.Final
- 6.0.2.Final
+ 2.0.1.Final
+ 6.0.7.Final
3.0.0
2.2.6
+ 5.0.2.RELEASE
@@ -21,12 +22,6 @@
-
- javax.validation
- validation-api
- ${validation-api.version}
-
-
org.hibernate
hibernate-validator
@@ -50,6 +45,16 @@
javax.el
${javax.el.version}
+
+ org.springframework
+ spring-context
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-test
+ ${org.springframework.version}
+
diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/MethodValidationConfig.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/MethodValidationConfig.java
new file mode 100644
index 0000000000..206a145337
--- /dev/null
+++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/MethodValidationConfig.java
@@ -0,0 +1,38 @@
+package org.baeldung.javaxval.methodvalidation;
+
+import org.baeldung.javaxval.methodvalidation.model.Customer;
+import org.baeldung.javaxval.methodvalidation.model.Reservation;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
+
+import java.time.LocalDate;
+
+@Configuration
+@ComponentScan({ "org.baeldung.javaxval.methodvalidation.model" })
+public class MethodValidationConfig {
+
+ @Bean
+ public MethodValidationPostProcessor methodValidationPostProcessor() {
+ return new MethodValidationPostProcessor();
+ }
+
+ @Bean("customer")
+ @Scope(BeanDefinition.SCOPE_PROTOTYPE)
+ public Customer customer(String firstName, String lastName) {
+
+ Customer customer = new Customer(firstName, lastName);
+ return customer;
+ }
+
+ @Bean("reservation")
+ @Scope(BeanDefinition.SCOPE_PROTOTYPE)
+ public Reservation reservation(LocalDate begin, LocalDate end, Customer customer, int room) {
+
+ Reservation reservation = new Reservation(begin, end, customer, room);
+ return reservation;
+ }
+}
diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java
new file mode 100644
index 0000000000..f1c97760d7
--- /dev/null
+++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java
@@ -0,0 +1,25 @@
+package org.baeldung.javaxval.methodvalidation.constraints;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraintvalidation.SupportedValidationTarget;
+import javax.validation.constraintvalidation.ValidationTarget;
+import java.time.LocalDate;
+
+@SupportedValidationTarget(ValidationTarget.PARAMETERS)
+public class ConsistentDateParameterValidator implements ConstraintValidator {
+
+ @Override
+ public boolean isValid(Object[] value, ConstraintValidatorContext context) {
+
+ if (value[0] == null || value[1] == null) {
+ return true;
+ }
+
+ if (!(value[0] instanceof LocalDate) || !(value[1] instanceof LocalDate)) {
+ throw new IllegalArgumentException("Illegal method signature, expected two parameters of type LocalDate.");
+ }
+
+ return ((LocalDate) value[0]).isAfter(LocalDate.now()) && ((LocalDate) value[0]).isBefore((LocalDate) value[1]);
+ }
+}
diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java
new file mode 100644
index 0000000000..6b321f545c
--- /dev/null
+++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java
@@ -0,0 +1,23 @@
+package org.baeldung.javaxval.methodvalidation.constraints;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Constraint(validatedBy = ConsistentDateParameterValidator.class)
+@Target({ METHOD, CONSTRUCTOR })
+@Retention(RUNTIME)
+@Documented
+public @interface ConsistentDateParameters {
+
+ String message() default "End date must be after begin date and both must be in the future";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+}
diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java
new file mode 100644
index 0000000000..f9cdea1483
--- /dev/null
+++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java
@@ -0,0 +1,24 @@
+package org.baeldung.javaxval.methodvalidation.constraints;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Constraint(validatedBy = ValidReservationValidator.class)
+@Target({ METHOD, CONSTRUCTOR })
+@Retention(RUNTIME)
+@Documented
+public @interface ValidReservation {
+
+ String message() default "End date must be after begin date and both must be in the future, room number must be bigger than 0";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+}
diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java
new file mode 100644
index 0000000000..7b730480ed
--- /dev/null
+++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java
@@ -0,0 +1,32 @@
+package org.baeldung.javaxval.methodvalidation.constraints;
+
+import org.baeldung.javaxval.methodvalidation.model.Reservation;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.time.LocalDate;
+
+public class ValidReservationValidator implements ConstraintValidator {
+
+ @Override
+ public boolean isValid(Reservation reservation, ConstraintValidatorContext context) {
+
+ if (reservation == null) {
+ return true;
+ }
+
+ if (!(reservation instanceof Reservation)) {
+ throw new IllegalArgumentException("Illegal method signature, expected parameter of type Reservation.");
+ }
+
+ if (reservation.getBegin() == null || reservation.getEnd() == null || reservation.getCustomer() == null) {
+ return false;
+ }
+
+ return (reservation.getBegin()
+ .isAfter(LocalDate.now())
+ && reservation.getBegin()
+ .isBefore(reservation.getEnd())
+ && reservation.getRoom() > 0);
+ }
+}
diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java
new file mode 100644
index 0000000000..fe9ad7080e
--- /dev/null
+++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java
@@ -0,0 +1,41 @@
+package org.baeldung.javaxval.methodvalidation.model;
+
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+@Validated
+public class Customer {
+
+ @Size(min = 5, max = 200)
+ private String firstName;
+
+ @Size(min = 5, max = 200)
+ private String lastName;
+
+ public Customer(@Size(min = 5, max = 200) @NotNull String firstName, @Size(min = 5, max = 200) @NotNull String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public Customer() {
+
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Reservation.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Reservation.java
new file mode 100644
index 0000000000..a8c01d2be1
--- /dev/null
+++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Reservation.java
@@ -0,0 +1,64 @@
+package org.baeldung.javaxval.methodvalidation.model;
+
+import org.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters;
+import org.baeldung.javaxval.methodvalidation.constraints.ValidReservation;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Positive;
+import java.time.LocalDate;
+
+@Validated
+public class Reservation {
+
+ private LocalDate begin;
+
+ private LocalDate end;
+
+ @Valid
+ private Customer customer;
+
+ @Positive
+ private int room;
+
+ @ConsistentDateParameters
+ @ValidReservation
+ public Reservation(LocalDate begin, LocalDate end, Customer customer, int room) {
+ this.begin = begin;
+ this.end = end;
+ this.customer = customer;
+ this.room = room;
+ }
+
+ public LocalDate getBegin() {
+ return begin;
+ }
+
+ public void setBegin(LocalDate begin) {
+ this.begin = begin;
+ }
+
+ public LocalDate getEnd() {
+ return end;
+ }
+
+ public void setEnd(LocalDate end) {
+ this.end = end;
+ }
+
+ public Customer getCustomer() {
+ return customer;
+ }
+
+ public void setCustomer(Customer customer) {
+ this.customer = customer;
+ }
+
+ public int getRoom() {
+ return room;
+ }
+
+ public void setRoom(int room) {
+ this.room = room;
+ }
+}
diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/ReservationManagement.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/ReservationManagement.java
new file mode 100644
index 0000000000..f6fec1a15d
--- /dev/null
+++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/ReservationManagement.java
@@ -0,0 +1,50 @@
+package org.baeldung.javaxval.methodvalidation.model;
+
+import org.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters;
+import org.baeldung.javaxval.methodvalidation.constraints.ValidReservation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Controller;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+import java.time.LocalDate;
+import java.util.List;
+
+@Controller
+@Validated
+public class ReservationManagement {
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @ConsistentDateParameters
+ public void createReservation(LocalDate begin, LocalDate end, @NotNull Customer customer) {
+
+ // ...
+ }
+
+ public void createReservation(@NotNull @Future LocalDate begin, @Min(1) int duration, @NotNull Customer customer) {
+
+ // ...
+ }
+
+ public void createReservation(@Valid Reservation reservation) {
+
+ // ...
+ }
+
+ @NotNull
+ @Size(min = 1)
+ public List<@NotNull Customer> getAllCustomers() {
+
+ return null;
+ }
+
+ @Valid
+ public Reservation getReservationById(int id) {
+
+ return null;
+ }
+}
diff --git a/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java
new file mode 100644
index 0000000000..2363bf8f5d
--- /dev/null
+++ b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java
@@ -0,0 +1,97 @@
+package org.baeldung.javaxval.methodvalidation;
+
+import org.baeldung.javaxval.methodvalidation.model.Customer;
+import org.baeldung.javaxval.methodvalidation.model.Reservation;
+import org.baeldung.javaxval.methodvalidation.model.ReservationManagement;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import javax.validation.ConstraintViolationException;
+import java.time.LocalDate;
+import java.util.List;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { MethodValidationConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class ContainerValidationIntegrationTest {
+
+ @Autowired
+ ReservationManagement reservationManagement;
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void whenValidationWithInvalidMethodParameters_thenConstraintViolationException() {
+
+ exception.expect(ConstraintViolationException.class);
+ reservationManagement.createReservation(LocalDate.now(), 0, null);
+ }
+
+ @Test
+ public void whenValidationWithValidMethodParameters_thenNoException() {
+
+ reservationManagement.createReservation(LocalDate.now()
+ .plusDays(1), 1, new Customer("William", "Smith"));
+ }
+
+ @Test
+ public void whenCrossParameterValidationWithInvalidParameters_thenConstraintViolationException() {
+
+ exception.expect(ConstraintViolationException.class);
+ reservationManagement.createReservation(LocalDate.now(), LocalDate.now(), null);
+ }
+
+ @Test
+ public void whenCrossParameterValidationWithValidParameters_thenNoException() {
+
+ reservationManagement.createReservation(LocalDate.now()
+ .plusDays(1),
+ LocalDate.now()
+ .plusDays(2),
+ new Customer("William", "Smith"));
+ }
+
+ @Test
+ public void whenValidationWithInvalidReturnValue_thenConstraintViolationException() {
+
+ exception.expect(ConstraintViolationException.class);
+ List list = reservationManagement.getAllCustomers();
+ }
+
+ @Test
+ public void whenValidationWithInvalidCascadedValue_thenConstraintViolationException() {
+
+ Customer customer = new Customer();
+ customer.setFirstName("John");
+ customer.setLastName("Doe");
+ Reservation reservation = new Reservation(LocalDate.now()
+ .plusDays(1),
+ LocalDate.now()
+ .plusDays(2),
+ customer, 1);
+
+ exception.expect(ConstraintViolationException.class);
+ reservationManagement.createReservation(reservation);
+ }
+
+ @Test
+ public void whenValidationWithValidCascadedValue_thenCNoException() {
+
+ Customer customer = new Customer();
+ customer.setFirstName("William");
+ customer.setLastName("Smith");
+ Reservation reservation = new Reservation(LocalDate.now()
+ .plusDays(1),
+ LocalDate.now()
+ .plusDays(2),
+ customer, 1);
+
+ reservationManagement.createReservation(reservation);
+ }
+}
diff --git a/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java
new file mode 100644
index 0000000000..6b53d3a107
--- /dev/null
+++ b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java
@@ -0,0 +1,209 @@
+package org.baeldung.javaxval.methodvalidation;
+
+import org.baeldung.javaxval.methodvalidation.model.Customer;
+import org.baeldung.javaxval.methodvalidation.model.Reservation;
+import org.baeldung.javaxval.methodvalidation.model.ReservationManagement;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.ValidatorFactory;
+import javax.validation.executable.ExecutableValidator;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.time.LocalDate;
+import java.util.Collections;
+import java.util.Set;
+
+public class ValidationIntegrationTest {
+
+ private ExecutableValidator executableValidator;
+
+ @Before
+ public void getExecutableValidator() {
+
+ ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
+ this.executableValidator = factory.getValidator()
+ .forExecutables();
+ }
+
+ @Test
+ public void whenValidationWithInvalidMethodParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
+
+ ReservationManagement object = new ReservationManagement();
+ Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, int.class, Customer.class);
+ Object[] parameterValues = { LocalDate.now(), 0, null };
+ Set> violations = executableValidator.validateParameters(object, method, parameterValues);
+
+ assertEquals(3, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithValidMethodParameters_thenZeroVoilations() throws NoSuchMethodException {
+
+ ReservationManagement object = new ReservationManagement();
+ Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, int.class, Customer.class);
+ Object[] parameterValues = { LocalDate.now()
+ .plusDays(1), 1, new Customer("John", "Doe") };
+ Set> violations = executableValidator.validateParameters(object, method, parameterValues);
+
+ assertEquals(0, violations.size());
+ }
+
+ @Test
+ public void whenCrossParameterValidationWithInvalidParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
+
+ ReservationManagement object = new ReservationManagement();
+ Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, LocalDate.class, Customer.class);
+ Object[] parameterValues = { LocalDate.now(), LocalDate.now(), new Customer("John", "Doe") };
+ Set> violations = executableValidator.validateParameters(object, method, parameterValues);
+
+ assertEquals(1, violations.size());
+ }
+
+ @Test
+ public void whenCrossParameterValidationWithValidParameters_thenZeroVoilations() throws NoSuchMethodException {
+
+ ReservationManagement object = new ReservationManagement();
+ Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, LocalDate.class, Customer.class);
+ Object[] parameterValues = { LocalDate.now()
+ .plusDays(1),
+ LocalDate.now()
+ .plusDays(2),
+ new Customer("John", "Doe") };
+ Set> violations = executableValidator.validateParameters(object, method, parameterValues);
+
+ assertEquals(0, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithInvalidConstructorParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
+
+ Constructor constructor = Customer.class.getConstructor(String.class, String.class);
+ Object[] parameterValues = { "John", "Doe" };
+ Set> violations = executableValidator.validateConstructorParameters(constructor, parameterValues);
+
+ assertEquals(2, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithValidConstructorParameters_thenZeroVoilations() throws NoSuchMethodException {
+
+ Constructor constructor = Customer.class.getConstructor(String.class, String.class);
+ Object[] parameterValues = { "William", "Smith" };
+ Set> violations = executableValidator.validateConstructorParameters(constructor, parameterValues);
+
+ assertEquals(0, violations.size());
+ }
+
+ @Test
+ public void whenCrossParameterValidationWithInvalidConstructorParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
+
+ Constructor constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class);
+ Object[] parameterValues = { LocalDate.now(), LocalDate.now(), new Customer("William", "Smith"), 1 };
+ Set> violations = executableValidator.validateConstructorParameters(constructor, parameterValues);
+
+ assertEquals(1, violations.size());
+ }
+
+ @Test
+ public void whenCrossParameterValidationWithValidConstructorParameters_thenZeroVoilations() throws NoSuchMethodException {
+
+ Constructor constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class);
+ Object[] parameterValues = { LocalDate.now()
+ .plusDays(1),
+ LocalDate.now()
+ .plusDays(2),
+ new Customer("William", "Smith"), 1 };
+ Set> violations = executableValidator.validateConstructorParameters(constructor, parameterValues);
+
+ assertEquals(0, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithInvalidReturnValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
+
+ ReservationManagement object = new ReservationManagement();
+ Method method = ReservationManagement.class.getMethod("getAllCustomers");
+ Object returnValue = Collections. emptyList();
+ Set> violations = executableValidator.validateReturnValue(object, method, returnValue);
+
+ assertEquals(1, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithValidReturnValue_thenZeroVoilations() throws NoSuchMethodException {
+
+ ReservationManagement object = new ReservationManagement();
+ Method method = ReservationManagement.class.getMethod("getAllCustomers");
+ Object returnValue = Collections.singletonList(new Customer("William", "Smith"));
+ Set> violations = executableValidator.validateReturnValue(object, method, returnValue);
+
+ assertEquals(0, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithInvalidConstructorReturnValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
+
+ Constructor constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class);
+ Reservation createdObject = new Reservation(LocalDate.now(), LocalDate.now(), new Customer("William", "Smith"), 0);
+ Set> violations = executableValidator.validateConstructorReturnValue(constructor, createdObject);
+
+ assertEquals(1, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithValidConstructorReturnValue_thenZeroVoilations() throws NoSuchMethodException {
+
+ Constructor constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class);
+ Reservation createdObject = new Reservation(LocalDate.now()
+ .plusDays(1),
+ LocalDate.now()
+ .plusDays(2),
+ new Customer("William", "Smith"), 1);
+ Set> violations = executableValidator.validateConstructorReturnValue(constructor, createdObject);
+
+ assertEquals(0, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithInvalidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
+
+ ReservationManagement object = new ReservationManagement();
+ Method method = ReservationManagement.class.getMethod("createReservation", Reservation.class);
+ Customer customer = new Customer();
+ customer.setFirstName("John");
+ customer.setLastName("Doe");
+ Reservation reservation = new Reservation(LocalDate.now()
+ .plusDays(1),
+ LocalDate.now()
+ .plusDays(2),
+ customer, 1);
+ Object[] parameterValues = { reservation };
+ Set> violations = executableValidator.validateParameters(object, method, parameterValues);
+
+ assertEquals(2, violations.size());
+ }
+
+ @Test
+ public void whenValidationWithValidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
+
+ ReservationManagement object = new ReservationManagement();
+ Method method = ReservationManagement.class.getMethod("createReservation", Reservation.class);
+ Customer customer = new Customer();
+ customer.setFirstName("William");
+ customer.setLastName("Smith");
+ Reservation reservation = new Reservation(LocalDate.now()
+ .plusDays(1),
+ LocalDate.now()
+ .plusDays(2),
+ customer, 1);
+ Object[] parameterValues = { reservation };
+ Set> violations = executableValidator.validateParameters(object, method, parameterValues);
+
+ assertEquals(0, violations.size());
+ }
+
+}