Bean Validation como validar um atributo que é um objeto de composição ?

Olá ! gostaria de uma luz quanto a realizar a validação de um objeto que faz parte de um outro objeto (composição) … acontece que tenho uma classe Conta que, a ele, tem um atributo Orcamento … fato é que consigo validar os atributos simples de Conta mas não consigo validar os atributos que compoe Orcamento.

Estou usando spring mvc.

@Entity
public class ContaPublica extends Conta{
    
    @Column(nullable = false)
    @NotNull @Min(2000) @Max(3000)
    private int anoExercicio;
    @Embedded @NotNull
    private Orcamento orcamento;
    .....
}

@Embeddable
public class Orcamento implements Serializable {
    
    @Column(scale = 2) @DecimalMin("0.00") @Digits(integer=6, fraction=2)
    private BigDecimal loa;
    @Column(scale = 2) @DecimalMin("0.00") @Digits(integer=6, fraction=2)
    private BigDecimal ep;
    @Column(scale = 2) @DecimalMin("0.00") @Digits(integer=6, fraction=2)
    private BigDecimal outros;
    @Column(scale = 2) @DecimalMin("0.00") @Digits(integer=6, fraction=2)
    private BigDecimal autorizado;
   ......
}

quando executo o método de salvar ele só me retorna os erros que estiverem na superclasse e classe filha, ou seja, Conta e ContaPublica.

como resolvo para chegar até contaPublica.orcamento ???

Espero que ainda te ajude, mas é mais ou menos assim…

//Anotação

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = OrcamentoValidador.class)
public @interface OrcamentoValido {
    String message() default "tem algo errado";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    Class<Orcamento> value();
}

//implementação da validação

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class OrcamentoValidador implements ConstraintValidator<OrcamentoValido, Orcamento> {
	@Override
	public boolean isValid(Orcamento value, ConstraintValidatorContext context) {
		// TODO: implementar regras pra validar o orcamento
		//return true se for válido ou false caso contrário
		return true;
	}
	@Override
	public void initialize(Orcamento orcamento) {
	}
}


@OrcamentoValido(value = Orcamento.class)
public class Orcamento {
...
...
}

É só anotar o campo orcamento com @Valid.

Mas como a @Valid saberá que Orcamento é válido ou não?

O @Valid pode ser usado em um atributo que é outro objeto que também possui validação. Assim a validação será em cascata, ou seja, irá validar o objeto contaPublica e depois orçamento.