title: Spring @Validated annotation prevents @ConfigurationProproperties value injection, why?
body: <p>I am trying with <code>@ConfigurationProperties</code> and I find two things:</p>
  
  <ul>
  <li>for tests to work, I have to put configuration properties files (yml) in <code>test</code> package; setters and an empty constructor are required. </li>
  <li>If I annotated the class with <code>@Validated</code>, injection just fails with all <code>null</code> values.</li>
  </ul>
  
  <p>If you say the first one is understandable, and the second one? Why?</p>
  
  <p>The purpose is to validate configuration properties injection, so that crucial properties values should not be absent when the application launches.</p>
  
  <p>I have this yaml to map:</p>
  
  <pre><code>accertify:
    fr:
      merchant1:
        host: "sandbox.accertify.dev"
        protocol: "https"
        user: "fraud"
        password: "temporal"
        merchant: "merchant1FR"
      merchant2:
        host: "sandbox.accertify.dev"
        protocol: "https"
        user: "fraud"
        password: "temporal"
        merchant: "merchant2FR"
    es:
      merchant1:
        host: "sandbox.accertify.dev"
        protocol: "https"
        user: "fraud"
        password: "temporal"
        merchant: "merchant1ES"
      merchant2:
        host: "sandbox.accertify.dev"
        protocol: "https"
        user: "fraud"
        password: "temporal"
        merchant: "merchant2ES"
  </code></pre>
  
  <p>I have this class to mapping nested configurations:</p>
  
  <pre><code>import com.westerngun.fraud.jfps.dto.provider.accertify.country.ConfigurationEs;
  import com.westerngun.fraud.jfps.dto.provider.accertify.country.ConfigurationFr;
  import com.westerngun.fraud.jfps.service.client.ConnectionDetailsInterface;
  import lombok.AllArgsConstructor;
  import lombok.Getter;
  import lombok.NoArgsConstructor;
  import lombok.Setter;
  import org.springframework.boot.context.properties.ConfigurationProperties;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.validation.annotation.Validated;
  
  import javax.validation.Valid;
  
  /**
   * Class to read Accertify provider connection credentials.
   */
  @Getter
  @Setter
  @Configuration
  @ConfigurationProperties(prefix = "accertify")
  @Validated   // &lt;--- this seems the problem
  @NoArgsConstructor
  @AllArgsConstructor
  public class AccertifyConnectionDetail extends ConnectionDetails {
  
      @Valid
      private ConfigurationFr fr;
  
      @Valid
      private ConfigurationEs es;
  }
  </code></pre>
  
  <p>And, its interface:</p>
  
  <pre><code>public abstract class ConnectionDetails {
      public abstract ConfigurationFr getFr();
      public abstract ConfigurationEs getEs();
  }
  </code></pre>
  
  <p>And, <code>ConfigurationEs</code> and <code>ConfigurationFr</code> are both subclass of:</p>
  
  <pre><code>@Component
  public class CountryConfigDetail {
      @Getter
      @Setter
      @Valid
      private Merchant1 merchant1;
  
      @Getter
      @Setter
      @Valid
      private Merchant2 merchant2;
  }
  </code></pre>
  
  <p><code>Merchant1</code> and <code>Merchant2</code> are subclass of :</p>
  
  <pre><code>@Data
  @Component
  public class MerchantConfigDetail {
  
      @NotEmpty
      @NotNull
      private String user;
  
      @NotEmpty
      @NotNull
      private String password;
  
      ...
      @NotEmpty
      @NotNull
      private Map&lt;String, String&gt; headers;
  }
  </code></pre>
  
  <p>When I try to inject into some <code>@Autowired</code> tests without <code>@Validated</code> in the first class, it works(<code>fr</code> and <code>es</code> have values in the yml file)</p>
  
  <p><a href="https://i.stack.imgur.com/XWcmu.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XWcmu.png" alt="enter image description here"></a></p>
  
  <p>When I add @Validated, <code>fr</code> and <code>es</code> are null.</p>
  
  <p>Test:</p>
  
  <pre><code>@RunWith(SpringRunner.class)
  @SpringBootTest
  public class AccertifyConfigurationTest {
  
      @Autowired
      private AccertifyConnectionDetail accertifyConnectionDetail; // &lt;--- this field should be injected
  
  
      @Test
      public void givenAAccertifyClientService_WhenClientIsBuild_ShouldHaveTheProviderConfigurationCorrect() {
          AccertifyConfiguration accertifyConfiguration = new AccertifyConfiguration(accertifyConnectionDetail);
          accertifyConfiguration.buildConfiguration("FR", "Merchant1");
  
          Assert.assertEquals("fraud", accertifyConfiguration.getUser());
          Assert.assertEquals("temporal", accertifyConfiguration.getPassword());
          Assert.assertTrue(accertifyConfiguration.getHost().startsWith("sandbox.accertify."));
          Assert.assertEquals("merchant1FR", accertifyConfiguration.getMerchantCode());
      }
  ...
  </code></pre>