2

I'm trying to validate my JPA Entity with @Valid like this:

public static void persist(@Valid Object o)

It worked fine for a while but now it stopped working and I'm not sure why. I tried to do it manually inside the persist method, and it works as expected:

    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator = factory.getValidator();

    Set<ConstraintViolation<Object>> constraintViolations = validator.validate(o);

    if (!constraintViolations.isEmpty()) {
        throw new ConstraintViolationException(constraintViolations);
    }

What could be happening or how can I debug this?

0

2 Answers 2

4

Method Validations is only available starting in bean validation v 1.1 (e.g. hibernate validator 5.x impl) which is part of Java EE 7 only. On top of that to have it working without extra specific BV code your method must be part of a component which is integrated with bean validation (eg. CDI Beans, JAX-RS Resource). Your custom code works because you do not use method validation but rather BV constraints which are defined directly on your object.

6
  • That seems like the correct answer, but could you please elaborate more on the "your method must be part of a component which is integrated with bean validation" part? Or point me to some reading? Thanks!
    – diogocarmo
    Commented Sep 16, 2015 at 18:25
  • Are you using BV in a JAVA EE managed environment (wildfly, websphere, GF...)? If yes then check the Java EE version your server comply to. If it is Java EE 7 then I suggest to use CDI and declare your method inside this kind of component. planet.jboss.org/post/…
    – Franck
    Commented Sep 16, 2015 at 18:36
  • We're using Jersey + Grizzly in a Java 8 VM. I believe Java Bean Validation is working, so I guess the Java EE version is >= 7. I'm going to try your suggestion and use CDI (but first, understand how does that works).
    – diogocarmo
    Commented Sep 16, 2015 at 19:04
  • Grizzly is not a Java EE compliant server and it seems to be not even compliant to the Servlet specification according to this post:stackoverflow.com/questions/17224270/….
    – Franck
    Commented Sep 16, 2015 at 19:40
  • Grizzly website (grizzly.java.net/dependencies.html), only mentions that it's not fully compliant to Servlet specification - doesn't say anything about Java EE - where did you read that?
    – diogocarmo
    Commented Sep 16, 2015 at 19:52
1

Won't work on arbitrary services. In Jersey it will only work for resource methods. So validate the incoming DTO in your resource method.

@POST
public Response post(@Valid SomeDTO dto) {}

See more at Bean Validation Support


UPDATE

So to answer the OP's comment about how we can make it work on arbitrary services, I created a small project that you can plug and play into your application.

You can find it on GitHub (jersey-hk2-validate).

Please look at the tests in the project. You will find a complete JPA example in there also.

Usage

Clone, build, and add it your Maven project

public interface ServiceContract {
    void save(Model model);
}

public class ServiceContractImpl implements ServiceContract, Validatable {
    @Override
    public void save(@Valid Model model) {}
}

Then use the ValidationFeature to bind the service

ValidationFeature feature = new ValidationFeature.Builder()
        .addSingletonClass(ServiceContractImpl.class, ServiceContract.class).build();
ResourceConfig config = new ResourceConfig();
config.register(feature);

The key point is to make your service implementation implement Validatable.

The details of the implementation are in the README. But the gist of it is that it makes use of HK2 AOP. So your services will need to be managed by HK2 for it to work. That is what the ValidationFeature does for you.

7
  • That sounds about right, previously I had success validating the incoming DTO. But our issue was: repeated constraints on both DTO and (the generated) Entity objects. Any idea how to work around this?
    – diogocarmo
    Commented Sep 17, 2015 at 1:39
  • I have a theory to make it so that you don't have to repeat the same explicit validation code you have above, but I don't have time to implement and test it right now. Maybe a little bit later I'll post my findings if it works out. Commented Sep 17, 2015 at 1:45
  • Great! I'm looking forward to it.
    – diogocarmo
    Commented Sep 17, 2015 at 1:47
  • Take a look at the update, and the GitHub project :-) Commented Sep 17, 2015 at 7:53
  • Wow that was amazing! I'm still going through your code to understand what you did, but I have a question: what's the advantage of using @Valid instead of doing a 'manual' validation as I was doing? Thank you for your help!
    – diogocarmo
    Commented Sep 17, 2015 at 13:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.