How to verify inputs for an abstract CMP setter method?

Discussions

EJB programming & troubleshooting: How to verify inputs for an abstract CMP setter method?

  1. For example, i wrote a CMP2 entity bean called UserBean, which has a setter method and a getter method for its CMP field called name:

    public abstract void setUserName(String name);
    public abstract String getUserName();

    These two methods are also declared in its remote interface in order that a user may change his name.

    When creating a UserBean and saving it into the database, i want that the bean's userName field is NOT empty. So in UserBean.ejbCreate(...) method, i check the name parameter: if it is null or empty, the method throws out a CreateException:

    public Integer ejbCreate(..., String name, ...)
    throws CreateException {
      ... ...
      if (name == null || name.trim().length() == 0) {
        throw new CreateException("User name is required");
      }
      ... ...
      setUserName(name);
      ... ...
      return null;
    }


    Thus, client may never create a UserBean with an empty name. But the problem is: if i get an existing UserBean instance, for example, by using UserHome.findByPrimaryKey(...) method, and then call its setUserName(...) method by passing an empty string to it, how can i check the parameter since the
    setter method must be abstract?

    One solution is to check my bean's CMP field in the method ejbStore(). This method is called by the EJB container when it decides to save the bean's data into the database. But when will this method be called? Only the container knows. That is to say, an empty name will not be detected until the container calls the ejbStore() method. That will be too late if i want to send an error message to the client immediately when he submits an empty name.

    Another solution is NOT to expose the setter method in the bean interface. Instead, i may provide a business method called setUserName2(String name). In the bean class, i may implement this business method like:

    public abstract void setUserName();
     
    ... ...
     
    public void setUserName2(String name)
    throws IllegalUserInputException {
      if (name == null || name.trim().length() == 0) {
        throw new IllegalUserInputException("Empty name is not allowed");
      }
      setUserName(name);
      return;
    }


    Hmmm... This seems a little stupid.

    So, what is the best solution?

    Thanks.
    heavyz
  2. Nobody replies... But finally i got the answer in EJB Design Patterns, page 200... In the second approch, if i change my method name setUserName2(..) to setUserNameField(..) in order that it follows the naming convention, that seems to be a correct solution...
  3. Nobody replies... But finally i got the answer in EJB Design Patterns, page 200... In the second approch, if i change my method name setUserName2(..) to setUserNameField(..) in order that it follows the naming convention, that seems to be a correct solution...

    I would create a "UserManager" stateless session bean which wraps all calls to the entity (facade pattern). here i would implement your business logic:

    if(null)
      throw userexception
    else
      entity.create(dto)

    In other words separate the business logic (eg session beans, helper classes etc) from persistance layer (eg entity beans).
  4. Thanks to your reply.
  5. I would NOT choose this approach, since validation should be in the entity, not the facade. The facade's resposibilities are NOT implement logic, but interfacing with clients and (perhaps) some flow-control. If you put logic in the facade, you might have to replicate that logic for every facade.

    Cheers and happy coding,
    Martin