6 Replies Latest reply on Dec 12, 2011 2:00 PM by lightguard

    Using @PersistenceContext in ConstraintValidator

    tboehnert

      Hi,
      I'm quite new to the world of java-enterprise technologies, so I hope my question isn't that stupid ;-)


      I wrote an ConstraintValidator to check if a given value already exists in the database.
      When I try to inject a EntityManager via @PersistenceContext, everything seems to be good.


      But once I try to use my EntityManager-object, I get an javax.persistence.PersistenceException caused by an javax.validation.ValidationException caused by an java.lang.NullPointerException.


      I found some tutorials regarding this problem, but they just seem to be valid for Seam < v3.



      I hope you can help me,
      Tobias

        • 1. Re: Using @PersistenceContext in ConstraintValidator
          gunnar.gunnar.morling.googlemail.com

          Hi Tobias,


          are you using the Seam Validation Module to set up your constraint validator? Otherwise dependency injection doesn't work within validators. You can find out more in the reference guide.


          I haven't tried injecting an EntityManager into a validator myself yet but IMO it should generally work on any EE application server (also see the Weld guide for information).


          Another useful piece of information might be this post in the Hibernate Validator wiki which describes an @Unique annotation probably similar to what you have in mind. It also mentions some potential issues related to phantom reads.


          Hope that helps,


          --Gunnar

          • 2. Re: Using @PersistenceContext in ConstraintValidator
            tboehnert

            Hi Gunnar, thanks for your reply!


            After putting the validation.xml into the correct META-INF-folder *cough*, it's working... but just for about 50% ;-)


            package de.foo.bar;
            
            import javax.persistence.EntityManager;
            import javax.persistence.PersistenceContext;
            import javax.validation.ConstraintValidator;
            import javax.validation.ConstraintValidatorContext;
            
            public class UniMacValidator implements ConstraintValidator<UniMac, String> {
            
                 @PersistenceContext
                 private EntityManager em;
            
                 @Override
                 public void initialize(UniMac constraintAnnotation) {
                 }
            
                 @Override
                 public boolean isValid(String macaddress,
                           ConstraintValidatorContext constraintContext) {
            
                      if (macaddress == null) {
                           return true;
                      }
                      
                      if(macExists(macaddress)) {
                           return false;
                      } else {
                           return true;
                      }
                 }
                 
                 private boolean macExists(String macaddress) {
                      System.out.println("em: "+em.toString()); //throws a nullpointer-exception when not initialized
            
                      if(macaddress.equals("de:ad:be:ef:13:37")) {  //simulates a DB-query ;-)
                           return true;
                      } else {
                           return false;
                      }
                 }
            }
            



            Alright... deploying the project works. Entering de:ad:be:ef:13:37 as MAC-address in the web-ui shows me an MAC aldready used-error, great!


            Saving the form in the web-ui with a valid, not-in-use MAC-address like de:ad:be:ef:13:38: nullpointer-exception in the line containing:

            System.out.println("em: "+em.toString());


            :-(


            I don't unterstand, why it's initialized the one time and the other not...

            • 3. Re: Using @PersistenceContext in ConstraintValidator
              tboehnert

              Aaalright:
              After a cleaning of the JBoss-Deploy-Folder I get another error when deploying the validator shown above:


              Caused by: java.lang.IllegalStateException: No bean manager is available. In order to use InjectingConstraintValidatorFactory, the javax.validation.Validator must either be retrieved via dependency injection or a bean manager must be available via JNDI.
              



              Can someone tell me how to fix this?



              Kind regards, Tobias

              • 4. Re: Using @PersistenceContext in ConstraintValidator
                lightguard

                Version of the server? Also, do have a beans.xml in WEB-INF?

                • 5. Re: Using @PersistenceContext in ConstraintValidator
                  tboehnert

                  Sorry for my late reply!


                  After i got the EntityManager-injection into an converter up and running, I was quite hopeful to do so with the validator, too.


                  But I still get an NullPointer-Exception when trying to access the EM-object :(


                  Used components


                   - hibernate-jpamodelgen 1.1.1.Final
                   - seam-solder 3.0.0.Final
                   - hibernate-validator 4.1.0.Final
                   - seam-validation 3.0.0.Final
                   - seam-faces 3.0.2.Final
                   - seam-persistence 3.0.0.Final
                   - joda-time 2.0 (dependency as workaround)
                   - prettyfaces-jsf2 3.3.2 (dependency as workaround)
                   - seam-solder-tooling 3.0.0.Final
                   - junit 4.8.1
                   - arquillian-junit
                  
                   - AS 7.0.2
                  



                  An empty (just the schema) beans.xml exists, also the validation.xml.

                  • 6. Re: Using @PersistenceContext in ConstraintValidator
                    lightguard

                    Have you tried a SMPC instead of the server one?