8 Replies Latest reply on Jul 1, 2009 4:45 PM by noonereally

    EntityHome and validation

      I have a problem with EntityHome objects and custom validation code. The problem is really simple but I don't know how to fix it in a seam manner. When working with EntityHome forms are directly bound to the managed entity instances. If I do a submit the setters of the entity will be invoked and hibernate will update the database automatically since the entity is still managed. My problem is that I need to do some additional validation before updating the database (i. e. checking for invalid value combinations). Usually I would do it in a save/update method before calling persist()/merge(). But in this case, the entity is updated automatically.


      How and where can I do these validation checks when using EntityHome objects?

        • 1. Re: EntityHome and validation

          Anybody can help please? I have absolutely no idea how to solve that problem in a seam manner.

          • 2. Re: EntityHome and validation
            sjmenden

            Change:



            @Override @Begin
            public void create() {
                super.create();
            }



            To:


            @Override @Begin(flushMode=FlushModeType.MANUAL)
            public void create() {
                super.create();
            }




            That will prevent the automatic flushing.  Now, think of how you are going to architect this next.  The first reaction might be to override the update and persist methods and remove the entityManager.flush(); method, but remember, it is needed for the persist method to actually set the ID, and the flush is the only effective line in the update method, so you should rearchitect your view or add more buttons.


            The other and better option, now that I am reading your original post again, is to forget everything I said above, and just override the persist method like so:




            @Transactional
               public String persist()
               {
                  //Do your additional validation here before persisting
                  getEntityManager().persist( getInstance() );
                  getEntityManager().flush();
                  assignId( PersistenceProvider.instance().getId( getInstance(), getEntityManager() ) );
                  createdMessage();
                  raiseAfterTransactionSuccessEvent();
                  return "persisted";
               }




            Also, have you considered writing your own hibernate validators?
                 

            • 3. Re: EntityHome and validation
              jguglielmin

              Within your custom validator, you could create an instance of import org.jboss.seam.ui.validator.ModelValidator and invoke the model validation. You can put it before or after your own validation and it uses the hibernate annotations on your entity bean (if this is what you are looking for).

              • 4. Re: EntityHome and validation

                Thank you very much! That was a good idea. Unfortunately, it didn't work for me but you gave me an idea how to solve it.


                The problem was caused by invoking the setters of the entity when a form was submitted. With the code snippet above you gave me an idea how to solve it. It is really simple:


                public String update() {
                    if (!valid()) {
                        // rollback the updates caused by the setters
                        Transaction.instance.rollback();
                    }
                    super.update();
                }
                



                I hope that this solution do not have any bad side effects. What do you think of this solution?

                • 5. Re: EntityHome and validation

                  Nice idea with the custom validator. Unfortunately, I couldn't find good documentation about that topic in a rush. Do you mean implementing the custom validation by using the EntityListeners like described here?


                  Do you have any good bookmarks regarding that topic?

                  • 6. Re: EntityHome and validation
                    leesy

                    Bit of a bump for this topic as I'm experiencing the same troubles but the suggested fixes aren't working for me.  Does anyone else have any other suggestions to get past this problem.  Here's my situation:


                    I've got an page with values bound to my EntityHome.  That contains an update method like below:


                    public String update() {
                      boolean errorsFound = false;
                    
                      if (StringUtils.isBlank(getInstance().getExternalId())) {
                        errorsFound = true;
                        getFacesMessages().addToControlFromResourceBundleOrDefault(
                            "selectedProjectExternalId", SEVERITY_ERROR,
                            "sso.manager.project.blankid",
                            "Please enter an external ID for the project.");
                      }
                    
                      // More checks for errors here
                    
                      if (errorsFound) {
                        return FAILURE.toString();
                      }
                      return super.update();
                    }



                    If I enter values that fail the validation, the error messages are shown but the database seems to still be updated to match the now incorrect data in the instance.  All the conversations in my application are started with FlushMode set to true (via pages.xml) so I'm not 100% why this is happening.

                    • 7. Re: EntityHome and validation
                      coolstone

                      I have the same problem, how to validate before update?For example, to check out whether some name is repeated in a table.

                      • 8. Re: EntityHome and validation
                        noonereally

                        This morning, I was reading about entity lifecycle listeners.  You can listen for lifecycle callbacks using annotations such as @PrePersist.  The callback method could be in the entity or in a separate class that's specified using the @EntityListeners annotation on the entity.  The argument that's passed to the listener is a reference to the bean.  Inside that callback method, you could do any validation that might be needed.


                        I have to admit that I've never used an entity lifecycle listener for validation, so I don't really know if this is a good idea.  I'm just throwing it out there to see if anyone has any thoughts on this.  I like the idea, because it allows you to avoid changing any of your existing code or code that's provided by Seam.