4 Replies Latest reply on May 26, 2008 9:08 PM by Stephen Friedrich

    Exception for duplication

    Mahmoud Maqboul Newbie

      Hey all


      if  there is any one can help me in doing exception and handling it on :


      I have two classes: persons and classes and the relation between them is many to many, so there is a third table between them: Registration.


      the problem was how to not making a person to register in the same class twice or more... I have solved this problem by annotation, by putting it in registration class.


      which is:


      @Entity
      @Table(name = "Registration", uniqueConstraints ={@UniqueConstraint(columnNames ={ "course", "person" })})
      public class Registration implements Serializable {
              
              //seam-gen attributes (you should probably edit these)
              
              private Long id;
              private Integer version;
              private CourseClass course;
              private Persons person;
              
          //add additional entity attributes
              
              //seam-gen attribute getters/setters with annotations (you probably should edit)
              
              
              
              @ManyToOne
              @JoinColumn(name ="course")
              
              public CourseClass getCourse() {
                      return course;
              }
      
              public void setCourse(CourseClass course) {
                      this.course = course;
              }
      
      
              @ManyToOne
              @JoinColumn (name = "person")
              public Persons getPerson() {
                      return person;
              }



      ......





      ok it is work but give me an error screen.... so I need a message to appear in this case instead of error page.


      error page is:
      HTTP Status 404 - /QAS/debug.seam


        • 1. Re: Exception for duplication
          Mahmoud Maqboul Newbie

          And most of the time it gives me this error page


          JBoss Seam Debug Page
          This page allows you to view and inspect any component in any Seam context associated with the current session.
          Conversations
          .
          .
          .
          .


          • 3. Re: Exception for duplication
            Fernando Montaño Expert

            have you tried putting something like this in pages.xml:



             <exception class="javax.persistence.EntityExistsException">
                    <end-conversation/>
                    <redirect view-id="/errorPage.xhtml">
                        <message severity="error">Item already exists</message>
                    </redirect>
                </exception>





            In the other hand you can also catch the exception (javax.persistence.EntityExistsException) in your bean class.



            HTH.

            • 4. Re: Exception for duplication
              Stephen Friedrich Novice

              Catching exceptions from the persistence layer really is a last resort.
              You should additionally check with a JSF validator. For example here's a validator that checks if a user id is already taken (which is quite similar to your scenario):


              /**
               * JSF validator that checks if a user name is already taken by another user.
               * The DB itself has a unique constraints on the user name column, so it is sufficient to check this on GUI level.
               */
              @Name("userIdUniqueValidator")
              @Validator
              @Transactional
              public class UserIdUniqueValidator implements javax.faces.validator.Validator, Serializable {
                   @In
                   private EntityManager entityManager;
              
                   @In(required = false)
                   private User selectedUser;
              
                  public UserIdUniqueValidator() {
                  }
              
                  public void validate(FacesContext facesContext, UIComponent component, Object value) throws ValidatorException {
                        try {
                             Long id = (Long) entityManager.createQuery("select user.id from User user where user.userId = :userId").setParameter("userId", value).getSingleResult();
                             if (selectedUser != null && !id.equals(selectedUser.getId())) {
                                  throw new ValidatorException(new FacesMessage("User Id is already in use. Please choose a different one."));
                             }
                        } catch (NoResultException nre) {
                             // fine - userName is unique.
                        }
                   }
              }
              



              You can use that validator (nested in another component tag) like


              <f:validator validatorId="userIdUniqueValidator"/>




              Of course you scenario is a little more tricky, because it involves two fields (person and course). You'll have to attach the validator to the seconds component and retrieve the first components submitted value from the component tree (assuming you have two fields for person and course).


              See here for more information
              Blog