Discussions

J2EE patterns: Place validation logic in Details Objects

  1. When designing enterprise applications using Entity Beans, validation logic must be placed in your ejbCreate() and in your "setter" methods in order to ensure that your transactions don't allow the creation of invalid data. A common business requirement is to also perform this type of validation on the client side (validating form submissions in the Servlet layer). The problem is that this validation logic is usually duplicated in the servlet layer and the EJB layer.

    As an example, consider a signup page, used to add users to a website. The contents of a signup page are typically a users name, address, phone number. This information could be stored in a User entity bean in the back end, where all of these fields will be validated. It is good design to also validate these fields at the servlet layer. That is, when a user submits his information through a signup form, a servlet should validate this data before passing it on to an EJB. The reason why this is good design is because if you rely on your EJB's to do validation, you will only be able to catch and report one error at a time (the one that through the exception). The result is that your form cannot return all the different errors the user may have done. Validating in the servlet layer is also better because you don't want to add the overhead calling and EJB (adds a network round trip, transactional overhead, etc.) to pass over the contents of the form if you know that it may contain errors.

    The problem now becomes, what to do about this duplication of code across tiers? The answer is to place your validation logic in the "setter" methods of your Details Objects. That is, validation for attributes like a users email address should go in the "setEmail(xxx)" method on a "UserDetails" object, and validation for a users name should go in a "setName(xxx)" method.

    Now in your user entity bean, you internally use its corresponding UserDetails object to validate in ejbCreate and setter methods. In your servlet layer, you can also use the details object to validate form input. If "setting" of all the form values succeeds (no exceptions have been thrown), then the form input is correct and can be sent to an EJB.

    Using this strategy will eliminate duplication of validation code, and also encapsulate validation logic. That is, instead of having hundreds of lines of ugly if/else blocks for tens of attributes, validation of each attribute is isolated in its own "setter method". Massive if/else structures are now replaced with smarter try/catch blocks, and validation/data logic is now placed in the same object that stores that data - a fundamental principle of good OO programming.

    Threaded Messages (28)

  2. I think this is a good idea as long as you only validate the format of the argument.
    I don't think you wan't to much code in the value object becurse you send it between web and application server so you want to keep the object as small as possible.

    Thomas
  3. I have used this pattern just for that purpose - validating the format of the input. (ie: is the email address valid?).

      You probably couldn't put business rules on the details objects anyway because they would require access to the ejb api's for more complex rules, and the details object is supposed to be just a data holder.

       A question about serialization... When you serialize an object, do you actually send the method implementations over the wire as well? That seems pretty bad. I thought you just send over the contents of the class and then the "other end" had to have a copy of the class you are sending in its classpath, that way you don't have send over method implementations and it wouldn't matter how large a classes methods are.

      Am I totally off here?

    Floyd
  4. No you are right Floyd.
    My mistake. Only the data is sent.
    Thanks for pointing this out.

    One thing that would be good about puting BO rules in value objects is that it would be more easy to migrate to an environmet without an EJB server.

    Thomas

  5. Floyd,

    You mentioned having to refer to the EJB api when implementing business rules. Do you mean you need to sometime reference other EJB's, or that some validation can't be performed without EJB specific funstionality? If so could you be explain or possibly give an example?
    Thanks.
    Jeff
  6. business vs data logic[ Go to top ]

    Do you mean you need to sometime reference other EJB's, or

    > that some validation can't be performed without EJB > specific funstionality?

       Yes, I meant exactly that. :) The only validation that can go into Details objects is "formatting logic". That is, each setter method can test its method parameters to ensure that the data being "Set" is not invalid. Anything beyond this type of logic, I would consider to be business logic, and may require access to other EJB's, access to ejb api's like the context, etc. All of this shouldn't be in the details object since it is just a data holder.

        As an example of business vs "formatting" logic, consider a "credit card" details object. A fictitious method "setCreditCardNumber" would require simple validation to ensure the number is valid (ie: no characters, appropriate length, etc), but a business logic type of validation would be a "credit history check", which could not go on the Details as it is just a simple data holder with no access to the outside world.

    hope this helps,

    Floyd
  7. business vs data logic[ Go to top ]

    Floyd,
    Thanks for the info! It really helped.
    Jeff
  8. business vs data logic[ Go to top ]

    I use the followgin coding rules for the validation.
    As Floyd point it out, there is 2 kind of validations rules:

    1- Syntaxic validation rules, contained in the StateHolder (= Detail):
      - Check the validate range
      - Check for not null

    2- Semantic validation rules, contained in the EJB:
      - Check rules which requiered to access to other components.
        i.e., "an account owner cannot own a saving account" (I know, that's a stupid rule, just an example.)
      - Check consistency between attributes, such as "the account balance must be greater than the account whitdraw limit".

    Up to now, I was duplicating the syntaxic validation rules in the StateHolder and the component. This time is over, I will use your nice pattern !

    Example:

    class Account implements EntityBean {
       public AccountStateHolder sh;

       public void setOwner(String owner) {
          sh.setOwner(owner);

          // Semantic validation rules
          if(.... )
             // rollback the transaction
             throw new IllegalArgumentException("...");
       }
       ...
    }

    class AccountStateHolder implements Serializable {

       public void setOwner(String owner) {
        // Syntaxic validation rules
        if(owner == null || owner.trim().lenght() == 0)
          throw new IllegalArgumentException("...");
         this.owner = owner;
       }
       ...
    }

    But the validation rules are also dusplicated in:
     - the Database: the component can delegate the check to the DB, but exceptions handling become hard to implement.

     - the HTML/JSP pages (Javascript) to check input errors on the client side to avoid stupid round trip Http requests.

    A solution could be to describe the validation rules in an XML file and to generate the code on the different layers of the architecture to insure the consistency: JavaScript/StateHolder/EJB/DB. Just a dream....

    Tibo.
  9. business vs data logic[ Go to top ]

    Actually, the thought of using XML for validation is not a dream, but a reality. You can use XML-schema to validate the input in an html form. For example, one can build the xml stream ( or DOM) from the HTML form parameters and validate the values against its XML-schema. The schema contains all the necessary validation (mostly syntax checks) rules. This can be done both at the client end in a browser that supports XML (for example, IE 5.0), and at the server end (in a servlet or a command bean).
  10. business vs data logic[ Go to top ]

    Pardon, but I am fairly new to EJB and distributed systems and from a client server background. I'm trying to piece together from this thread where and how to do specific validations in a disributed environment.
    An HTML based front end provides it's own interface problems for doing bulk data entry into an OLTP app so I'm going to use the example of using a Swing thin-client to reproduce a current client-server data entry screen.
    For example, a screen for entering an invoice has fields in a parent window corresponding to columns in an bill header table. A child window displays rows of records corresponding to rows in a bill line item table. All fields in both windows are edited and then saved at one time.
    However all the fields are validated at the time they are changed and they are not necessarily "format" validation. Each line item may have a prof id and a work code which have to be present in a prof table and code table, respectively, for the data to be valid for saving.
    This is business validation and should be done in the middle, right? But trying to set the mid tier value each time a UI value is changed in order to validate seems like a whole lot of network calls. On the other hand, sending that whole screens worth of input to the back at one time for validation doesn't seem practical either. How is this generally done?
    Thanks for any info -Tony
  11. Just a small note, only the contents of the value object would be sent back and forth, not the code.

    Also, it seems to be a good fit, putting the validation logic in the details objects, however putting other code there would not be a good idea.

    - Alex
  12. sorry about that last post, i see someone already pointed that out.

    :)

  13. I agree with Thomas.

    The validation based on business rules should reside
    on the business tier. You don't want BO-rules in serialized objects beeing passed to the client tier.




      
  14. There is a different (and perhaps, neater) way of getting around one of Floyd's premises: that the details of only one error can be returned from the entity bean at a time.

    One alternative would be to create a new exception class, InvalidDataException, say, that contains an enumeration of the various validation errors in the supplied data, with operations for adding errors and retrieving the enumeration.

    The validating code would just add details of each failing field (or combination of fields) to the newly created exception, then throw it at the end of the validation. The details could just be stored as field names, or even fully formatted error messages. As long as the client is aware of the protocol, no problem.

    This class could get reused heavily...

    Matt
    This would
  15. Thibault,

      I am glad you find the pattern useful. You also said that code will still be copied on the client side (ie: checking in javascript). I personally never do validation checks at the browser level, and avoid client side technologies like javascript like the plague. :) TheServerSide.com, and most real large websites do everything (including validation) on the server side of things, which provided the main need for my pattern, so that syntactic logic isn't duplicated in the servlets layer and the ejb layer. The extra HTTP requests are really not that bad. :)

    Matt,

       I like your idea. I never thought of doing that, yet now it seem so simple. :) I can think of a lot of places where your strategy would be good, however I would probably still stick to the current paradigm, because I really wouldn't want to hit the EJB Layer for requests that could be invalid if I can't help it. Unlike the extra http requests the Thibault mentioned, the RMI serialization of form contents and the transactional overhead of calling an EJB when this simple validation can be performed locally seems pretty bad for performance.

    Floyd
  16. A couple of concerns here. If we throw exceptions for some methods, but others succeed, then the Details object is in an strange, half correct, half incorrect state. I've read that exceptions should only be used for exceptional conditions. Validation errors are expected. I remember reading somewhere that they shouldn't be used for validation.

    So here are my thoughts, I must admit they aren't complete and welcome feedback.

    The Details object could have the following methods that could be abstracted into a base class:
     
    public void beginValidation(ValidationSummary v) {
       this.valSumm = v;
    }

    public ValidationSummary endValidation() {
       ValidationSummary v = this.valSum;
       this.valSum = null;
       return v;
    }

    The set method would have the following logic:
    public void setName(String name) throws ValidationException {
       // Validate name somehow
       ValidationError valErr = validateName(name);
       
       // See if in validation mode
       if(valErr != null) {
          // If we are, just add error to summary
          if(this.valSum != null) {
             this.valSumm.addError(valErr);
             return;
          }
          // Otherwise throw exception
          else {
             throw new ValidationException(valErr);
          }
       }

       // Passed validations so can set name
       this.name = name;
    }

    Updating the object will have to be done in 2 passes by the controlling logic. One that validates, then if no errors, one that sets. The set methods could still throw an exception in the case where a user tried to do an invalid set without first calling begin validation.

  17. I would like to comment on the difference between
    a) Using a details object that does 'format' validation before calling the EJB which does 'business' validation
    b) Having the EJB do all validation and returning an exception that refers to all bad fields.

    Option a) is more network-efficient but doesn't allow the user to see all their errors at once. If there is a format error in one of the fields and a business error in another, only the format error will be returned. It is only after there are no formatting errors that the user can see the business error.

  18. Floyd,

    You state that "TheServerSide.com, and most real large websites do everything (including validation) on the server side of things, which provided the main need for my pattern, so that syntactic logic isn't duplicated in the servlets layer and the ejb layer. The extra HTTP requests are really not that bad."

    There is still the problem that in an intranet environment the user does expect client-side validation. For example, why allow them to enter non-valid characters in currency fields, date fields, etc. They do not want to enter the whole form only to be told after submition that there is a simple syntax error. They want to be stopped being allowed to do so in the first place, where possible.


    At least this is a requirement for the applications I work on. I'm interested to know how one avoids the duplication in this case.

    Regards,
    Menno

  19. In O'Reilly's Enterprise JavaBeans, 2nd Edition, chapter 9 page 330, this concept is proposed as a way of ensuring that validation is only done in one Class, can be used in the UI and also guarantee that EJB data is valid. However there is a significant and, IMHO, important difference - no mutators on the dependant/details object.

    What is proposed is to create (immutable) 'Dependant Objects' that perform validation in their constructors - not in mutators (there are no mutators - see below). It is therefore impossible to construct an invalid dependant/details object.
    EJBs accepting these objects can be sure they are valid and GUIs constructing them can catch errors immediately in the presentation layer without bothering the EJBs.

    In addition, because there are no mutators on these objects, errors are not made in the client resulting from programmers 'forgetting' that the object was obtained from a remote EJB (see page 328 of the EJB book). ie. forgetting that objects obtained from EJBs are copies, not references to the original object held by the EJB.

    Channing
  20. Hi Floyd.
    I really like this pattern, and have used it many times, not only in EJB design. This pattern is generally a good way to place validatin logic in one place, avoiding duplicate validation of data.
    One thing to note about this pattern when used in EJB, though, is that you cannot be sure that object content is valid when an EJB method is called.
    Any client may subclass the value object, and change or eliminate the validation logic. Even on the server side, using a parameters may lead to running dynamically loaded code. One way of avoiding this is to disallow dynamic class loading. However, if you want to preserve polymorphism, you can use a different pattern. I call it Validator, even though I have never seen it documented.
    In this pattern, a Validator class is used as an abstract way to "validate" data. The semantic meaning of "validating" - whether syntatic or semantic validation are performed (or both) depends on the implementation of the Validator and may vary between layers. For example, the synatactic validation in your example is performed on the client side, while the semantic validation is performed on the EJB server.
    This pattern allows for validation logic to be moved between layers without impacting alot of application code.

    Another strong point about this pattern is that it seperates the data and the use of the data. Different applications may use the same data in different ways, while the data (details objects) remains the same. In practical use, this point is very important. I have had two projects where we had to use the same data in several different ways, and I think most projects reach such a point after a while.
    Another point regarding this pattern, is that it allows bottom-to-top validation, allowing each tier to validate the data up to a different degree.

    Regards
    Gal
  21. The Validator approach sounds interesting. Could you post some more detailed information? Maybe a separate pattern?

    Fried.
  22. How can I use this pattern to validate new instances of an CMP entity bean ?

    From various reading and from the "Mastering EJBs" course I understand that using value object ( details objects) is a smart thing to do - and the idea of using these also for validations logic also fits in nicely.

    Being new to EJBs I have the following problem :

    An instance of a CMP entity bean generally represents a row in a database table and creating a new instance of the EB also insert a row in the relevant table. How can I then get hold of an value object ( which is created directly or indirectly by the entity bean object ) to do the valiation that must take place ( at the client) before I do the insert into the database?

    There certainly must be solutions to this problem, but I have not seen any in the descriptions and discussions of this pattern.

    Tia, Kjell.
  23. Thats exactly where I'm staying at the moment. In a magazine I read, that an entity Bean could inherit the Value Object. Doing this, would solve the problem of having duplicate accessors (get / set) and would make it easier to have a clone of the Value Object for sending it to the client. I realy liked this sugestion but : In EJB 2.0 the get and set needs to be abstract ! Now the inheritance doesn't work anymore because the Value Object would already provide an implementation of the get / set ...

    I'm stil looking around to get a practical solution to avoid too mutch duplicate coding but providing a thight integration of the Value Object pattern along CMP.

    Thomas Christen
  24. I think a good design is wrapping your CMP with session bean, so let session bean do the validition for you.
  25. You mentioned here
    When designing enterprise applications using Entity Beans, validation logic must be placed .....

    Is this not a good idea to implement your Pattern ("Place Validation Logic In Details Objects Pattern") in Stateless Session Bean.

    Thanks,
    fa.
  26. OK this is an old thread - but I did want to determine what conclusion was reached.

    I had a number of comments on this approach

    For individual fields such as email address, phone number etc. Use a class - For example Phone with constructor arguments number in String format and Locale. The Phone class should validate (called through setters as you suggest). These classes then might provide additional features such as locale sensitive presentation (e.g. display country code when the user is from another country). Internally of course the Detail Object will hold the values in whatever type is needed. Duplication of coding effort is reduced since these classes should exist on server and client with perhaps a configuration to differentiate the level of checking depending on tier. This is much more in the spirit of OO.

    The detail class should exist in both web and business logic tier used by the business logic tier as a validation helper. The Business Tier would contain additionally server side validations perhaps as another helper.

    Right now I can't see any better way than setting all the values then interrogating the detail object for state - valid / invalid with the possibility to retrieve a collection of errors (codes etc.) that can be used with a Message Resource so that multilanguage is supported

    I don't like the setters throwing exceptions since the validation is not complete to all properties have been populated and the Detail Object cannot know that until it is told.

    Incidentally I assume that we should be able to pass the detail object (in form of value object) back to the EJB - I'm not sure how much we can then trust the object to be correctly validated - so a validate method is called once more.


  27. I am not sure what to call this pattern-could someone help- For our validation on Objects-We are using standard java beans(not ejb's) that "set" the data, before the actual Access Bean is used to create,update,or delete the EJB. The problem was that we had "lots" of data to validate, and were looking for a way to validate it more "dynamically."

    Each java bean(not ejb) has a "validator" class which basically has all of the valiation logic. Each method in the validator class can but does not always map over to the java bean getter methods. Somae validation values are loaded into the validator class via properties files(not the best design). Due to the significant number of fields in the java bean, we used the reflection api to dynamically validate all of the fields by calling the getMethods of the java bean class against the getMethods of the validator class. If the two match(with some string manipulation), we call getvalue on the java bean method and the corresponding validate method that checks the value. The result is that when we add validation methods to the validator class, there are no changes outside of that class(ie I don't have to code for it elsewhere). Also, methods that we don't want validated, we simply don't add to the validator class.
    Is this even a pattern? Does this resemble any existing patterns?
  28. Mathew,

      Your solution sounds interesting, albeit a bit difficult to understand from the description you gave. It sounds like a pattern to me, perhaps you should write up a more formal copy and post it as a pattern. There is a great need for validation patterns, as not many are out there.

    Floyd
  29. There is one thing maybe miss out here. That is how to validate the mandatory attibutes of a value object.

    It's very common that a domain value object must contain certain attributes such as a user id. But how can we force the client user to call the setUserID() when he constructs such a value object unless we only use constructors to set the values. One drawback of using constructor is it prevents the user to re-use the object.

    Thanks,
    JiRong