3

I develop application and found something I cant understand. I have created my custom validation annotation called @UsernameAvailable and implementation of ConstraintValidator.

I annotate some field of my entity with the annotation and I have added some System.out.println("something message"); inside ConstraintValidator isValid() method.

What I have noticed is that the validation method is called twice:

At first while the form on the page is submited and data is binded to entity. And then, second time when the entity is saved by JpaRepository (from Spring Data JPA)

But the difference is that, in my ConstraintValidator implementation I have some @Autowired dependencies and when validation takes place for the first time on "form submit validation" dependencies are injected properly.

And at the second time, while the isValid method is called on saving entity my @Autowired Service is null, why is that?

If you dont understand just read and watch that:

All of what I wrote is shown on this video: https://www.youtube.com/watch?v=rFf0CaxaHVc (best, start watching from 04:20 minute)

This is exact problem I have, why do I have to check nulls in isValid? Why is the service null?

Its quite imporant for me to understand that

azalut
  • 4,094
  • 7
  • 33
  • 46

1 Answers1

2

I have encountered the same issue in a Java EE (JSF/CDI/EJB/JPA) app. I think what is happening here is exactly the same.

You have two different containers where validation is performed here. From where the form is submitted (in my case a CDI managed bean), and from within the ejb when JPA creates and calls the validator prior to persisting.

For form validation the container creates a validator that supports injection. However, subsequent to form validation the entity will be submitted to an ejb service (may differ in your case) which in turn calls JPA/EntityManager to persist etc. JPA has a validation step prior to persisting, but does not create such a validator (with CDI capabilities) so that any injection attempt will fail as you have seen. There is no requirement in the JPA Spec to support injection in the validation step and I have tested with eclipseLink and Hibernate.

There will be several options available to get around this – but none would seem to be as elegant - atleast in scenarios such as yours - as having JPA support custom validators with CDI capabilities. So for the purpose of this answer I can confirm that the behaviour you observe is currently as specified/designed for the reasons given. I have had the same problem here EJB injection fails in custom ConstraintValidator on JPA persist.

Community
  • 1
  • 1
NickJI
  • 466
  • 3
  • 12
  • thanks! So you say there is validation step prior to persisting. Is there any way to disable it? After validating the bean on form submit nothing can happen, so its enough for me. Btw how strange, why cant all of the validators support injection?:) they should – azalut Jul 14 '15 at 07:52
  • @azalut - try adding NONE to your persistence.xml. Not sure why this is not supported. Good luck. – NickJI Jul 14 '15 at 11:19