# How can I get the root bean in a custom validator,When using field-level constraints field access strategy

**URL:** https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949
**Category:** Hibernate Validator
**Created:** [November 23, 2022, 8:26am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949 "2022-11-23T08:26:21Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![alan](https://avatars.discourse-cdn.com/v4/letter/a/a87d85/32.png) [@alan](https://discourse.hibernate.org/u/alan)
#### Post date: [November 23, 2022, 8:26am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/1 "2022-11-23T08:26:21Z")

</div>

Hi guys,  
I’m implement a custom corrrelation validator, just like this:  
**Correlation.java**

```auto
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Constraint(validatedBy = CorrelationValidator.class)
public @interface Correlation {
    String message() default "";
    String ref() default "";

    String refValue() default "";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

```

**User.java**

```auto
public class User {
    @Correlation(ref = "name", refValue = "alan", message = " when name is alan, the age can not be null")
    private Integer age;
    private Integer id;
    private String name;

 //getters and setters...
}

```

**CorrelationValidator.java**

```auto
public class CorrelationValidator implements ConstraintValidator<Correlation, String> {

    @Override
    public void initialize(Correlation constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        // I want to get the root bean instance User here and get the user.name to do a validation, but I can not obtain it from the constraintValidatorContext ;
        return true;
    }
}

```

I want to get the root bean instance User in the _CorrelationValidator .isValue()_ method and get the user.name to do a validation, but I can not obtain it from the constraintValidatorContext ;  
when I hava a look at your sources code ConstraintTree.java,I found I can obtain the root bean in _ValidationContext.getRootBean()_, I hope you can put _executionContext_ into the _isValue_ method.

**ConstraintTree.java**

```auto
	private <T, V> Set<ConstraintViolation<T>> validateSingleConstraint(ValidationContext<T> executionContext,
																		ValueContext<?, ?> valueContext,
																		ConstraintValidatorContextImpl constraintValidatorContext,
																		ConstraintValidator<A, V> validator) {
		boolean isValid;
		try {
			@SuppressWarnings("unchecked")
			V validatedValue = (V) valueContext.getCurrentValidatedValue();
			isValid = validator.isValid( validatedValue, constraintValidatorContext );
		}
		catch ( RuntimeException e ) {
			throw log.getExceptionDuringIsValidCallException( e );
		}
		if ( !isValid ) {
			//We do not add these violations yet, since we don't know how they are
			//going to influence the final boolean evaluation
			return executionContext.createConstraintViolations(
					valueContext, constraintValidatorContext
			);
		}
		return Collections.emptySet();
	}

```

if you hava a better solution please notice me, I will appreciate it.

---

<div class="post-metadata">

### Author: ![gsmet](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/gsmet/32/9_2.png) [@gsmet](https://discourse.hibernate.org/u/gsmet)
#### Post date: [November 23, 2022, 9:36am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/2 "2022-11-23T09:36:24Z")

</div>

Hi,

I think for now, the cleanest solution would be to use a class level constraint. That way, you can access the whole bean and check things there.

I don’t think it would be that hard to expose the root bean into `HibernateConstraintValidatorContext` (the Hibernate Validator-specific version of `ConstraintValidatorContext` that you can cast to) but I’m not convinced it’s a good idea from a design point of view.

Could you expose why a class level constraint is not a good solution for you?

---

<div class="post-metadata">

### Author: ![alan](https://avatars.discourse-cdn.com/v4/letter/a/a87d85/32.png) [@alan](https://discourse.hibernate.org/u/alan)
#### Post date: [November 23, 2022, 10:22am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/3 "2022-11-23T10:22:36Z")

</div>

that case, in order to get root bean I should add a class-leve annotation, I think it is not convenience, like this:  
**CorrelationOnClass.java**

```auto
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Constraint(validatedBy = CorrelationValidator.class)
public @interface CorrelationOnClass {
    String message() default "";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

```

**User.java**

```auto
@CorrelationOnClass
public class User {
    @Correlation(ref = "name", refValue = "alan", message = " when name is alan, the age can not be null")
    private Integer age;
    private Integer id;
    private String name;
   //getters and setters...
}

```

**Correlation.java**

```auto
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
public @interface Correlation {
    String message() default "";
    String ref() default "";

    String refValue() default "";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

```

**CorrelationValidator.java**

```auto
public class CorrelationValidator implements ConstraintValidator<CorrelationOnClass, Object> {

    @Override
    public void initialize(CorrelationOnClass constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(Object bean, ConstraintValidatorContext constraintValidatorContext) {
        Field[] fields = bean.getClass().getDeclaredFields();
        for (Field field : fields) {
            Correlation annotation = field.getAnnotation(Correlation.class);
            //get the feild value and do a validation
        }
        return true;
    }
}

```

---

<div class="post-metadata">

### Author: ![gsmet](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/gsmet/32/9_2.png) [@gsmet](https://discourse.hibernate.org/u/gsmet)
#### Post date: [November 23, 2022, 10:41am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/4 "2022-11-23T10:41:00Z")

</div>

Personally I think I would have made this thing less generic and have specific `CorrelationValidator`s for each class and implement the logic directly with the passed bean (that would be then of the right class directly).

If you want something generic, you will have to use some reflection, yes.

I’m just a bit nervous at the idea of breaking the encapsulation of a field validator. A bit worried that it could open a can of worms.

@mbekhta what do you think?

---

<div class="post-metadata">

### Author: ![mbekhta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/mbekhta/32/2044_2.png) [@mbekhta](https://discourse.hibernate.org/u/mbekhta)
#### Post date: [November 23, 2022, 11:23am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/5 "2022-11-23T11:23:00Z")

</div>

hmm, I agree that exposing the root object can potentially lead to exposing too much and open access to more “private data”.

In this particular case

> [@alan](#):
>
> `message = " when name is alan, the age can not be null"`

If what you are trying to do is to create some conditional validation, I’d suggest taking a look at writing a getter with `@AssertTrue` on it, something along these lines:

```auto
public class User {
	private Integer age;
	private Integer id;
	private String name;
	//getters and setters...
	
	@AssertTrue(message = " when name is alan, the age can not be null")
	public boolean isAgeValidForName(){
		return "alan".equalsIgnoreCase( name ) ? age != null : true;
	}
}

```

Also, if that User class is supposed to be converted to JSON - you might need to put an additional annotation on this getter, so it is not serialized into JSON (depending on what lib you are using for it).

You can have as many such getters as you need.

It might be that I’ve missed something but if you are planning on using the

> [@alan](#):
>
> ```auto
> @Correlation(ref = "name", refValue = "alan", message = " when name is alan, the age can not be null")
> private Integer age;
> 
> ```

in any other classes besides `User`, exposing the root object would still require you to do some reflection if you’d like to have a single ConstraintValidator implementation.

Another idea to consider - create an interface that exposes the fields that you are interested in (name/age) and implement it in all other classes, including `User` that way, you’d only have a single ConstraintValidator impl to validate the interface rather than generic `Object`.

---

<div class="post-metadata">

### Author: ![alan](https://avatars.discourse-cdn.com/v4/letter/a/a87d85/32.png) [@alan](https://discourse.hibernate.org/u/alan)
#### Post date: [November 23, 2022, 12:22pm UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/6 "2022-11-23T12:22:30Z")

</div>

Thank you for your answer, because we are writing a framework for our team, we need to deal with a lot of correlation verification so we need a more general and simple implementation.

---

<div class="post-metadata">

### Author: ![mbekhta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/mbekhta/32/2044_2.png) [@mbekhta](https://discourse.hibernate.org/u/mbekhta)
#### Post date: [November 23, 2022, 1:52pm UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/7 "2022-11-23T13:52:15Z")

</div>

I see … well in this case I’d also suggest taking a look at `@ScriptAssert` - this one allows you to write a simple validation script (let’s say in groovy) where you could place your conditional logic.

---

<div class="post-metadata">

### Author: ![alan](https://avatars.discourse-cdn.com/v4/letter/a/a87d85/32.png) [@alan](https://discourse.hibernate.org/u/alan)
#### Post date: [November 25, 2022, 9:31am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/8 "2022-11-25T09:31:21Z")

</div>

I wonder does the declaration of this method have to start with 'is '?

```auto
	@AssertTrue(message = " when name is alan, the age can not be null")
	public boolean isAgeValidForName(){
		return "alan".equalsIgnoreCase( name ) ? age != null : true;
	}

```

---

<div class="post-metadata">

### Author: ![mbekhta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/mbekhta/32/2044_2.png) [@mbekhta](https://discourse.hibernate.org/u/mbekhta)
#### Post date: [November 25, 2022, 9:55am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/9 "2022-11-25T09:55:31Z")

</div>

Such methods should follow the JavaBean convention. Otherwise, the validation will not be triggered. Please take a look at this [section of the documenttation](https://docs.jboss.org/hibernate/validator/6.2/reference/en-US/html_single/#section-getter-property-selection-strategy). It provides the details of what will be considered as a getter as well as how you can adjust that.

---

<div class="post-metadata">

### Author: ![iabmatos](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/iabmatos/32/2170_2.png) [@iabmatos](https://discourse.hibernate.org/u/iabmatos)
#### Post date: [December 19, 2022, 1:39am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/10 "2022-12-19T01:39:59Z")

</div>

I’ve got a similar need for accessing the root bean for validations and placed a question on StackOverflow ([Question about complex Java Beans Validation with Spring Boot and Vaadin in the front-end - Stack Overflow](https://stackoverflow.com/questions/74838699/question-about-complex-java-beans-validation-with-spring-boot-and-vaadin-in-the)), which I reproduce here:

I’ve got an Entity class with lots of fields, including a **status** to represent the progression of an object thru its life cycle, say “INITIAL”, “READY”, “SUSPENDED” and “CLOSED”. While at the “INITIAL” stage, all fields can be changed, a few can be changed while the object is “SUSPENDED”, very few fields can be changed while in the “READY” status, and once “CLOSED”, nothing more can be changed for that object.

So, _setName(@NotBlank String name)_ is fine, but that is not enough, as as the name can only be changed when _status_ is NOT CLOSED, but _setCurrency(@NotBlank String currency)_ can only be applied when _status_ is INITIAL, or SUSPENDED if other conditions are also valid. Thus, I need varying validations applied as pre-conditions to the **set…** method execution, not as Class-level validation.

There is more. The status is implemented as an **enum** , with a Finite State Machine defining the valid transitions from one state to another. And at each state transition, a number of business rules need to be applied to validate the data surrounding the core entity. So instead of using **setStatus(Status newStatus)**, I’m using **setStatusReady()**, **setStatusSuspended()**…

From all that I’ve found, most tutorials, articles, best practices and solutions cater for the syntactical validations at field or class level and cross-parameter method validations, while I’d **need access to whole Bean instance at the time of the method execution**.

So far, the “best” solution is from OVAL (see [OVal User Guide | oval](https://sebthom.github.io/oval/USERGUIDE.html#using-validate_with_method)), but that framework is not longer under development and OVal is not JSR303/JSR380 compliant.

So, what are your suggestions?

Thank you all."

---

<div class="post-metadata">

### Author: ![mbekhta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/mbekhta/32/2044_2.png) [@mbekhta](https://discourse.hibernate.org/u/mbekhta)
#### Post date: [December 19, 2022, 11:23am UTC](https://discourse.hibernate.org/t/how-can-i-get-the-root-bean-in-a-custom-validator-when-using-field-level-constraints-field-access-strategy/6949/11 "2022-12-19T11:23:09Z")

</div>

Hey Ismael,

It seems that there are a few concerns mixed in your use case. There’re groups of validation rules, bean modifications and state transitions.

For example:

> [@iabmatos](#):
>
> _setCurrency(@NotBlank String currency)_ can only be applied when _status_ is INITIAL, or SUSPENDED if other conditions are also valid

is more about business logic rather than POJO being valid. I’d suggest separating things:

- Starting from the entry point (controller/resource) - either have specific POJOs that describe the fields that can be modified in each state or have a generic POJO with all possible fields for any state and apply validation groups to it.
- At the service level, after an entity is retrieved from DB and its current status is identified, a specific “updater” is selected. By “updater” I mean a set of instructions that modify only the entity properties that can be changed in the current status.
- At the entity level, you can have a combination of property/class level constraints that check that the overall state of the object is valid.
