Blogs

SpringSource Blog

Validation logic (and my first post!)

Colin Yates

Hey all!

This is my first post since I joined Interface21 last month. My previous blog is now officially deprecated and I won't be updating it anymore.

So what is the subject of my first post (except to introduce myself)?  Validation logic.  It won't be a walkthrough of how to perform validation in the Spring framework, rather it will discuss a particular bug bear of mine :)

In particular, I would like to discuss exactly what should go into validation logic.  It seems to be a no-brainer answer; "logic to validate the specified data".  OK, that *is* a no-brainer but read on :) .
As you know, the Spring framework provides a nice abstraction layer for your validation, via the Errors and Validator interfaces.  In particular the Validator is where you apply your business specific validation rules to your populated domain object.  Spring's excellent binding support is responsible for updating your domain model based on some input, the validator is responsible for ensuring that the populated domain model is semantically correct.
So what is my bug bear?  Time and time again I keep running across applications that allow validation logic to trickle out of the validator and into the controllers (for web apps), or even worse into the middle tier.  Just before people start taking issue; I am not saying validation doesn't belong in the middle tier, I am saying that the Validator is the place to put validation logic!

The most common example of this is when you are adding a new entity, say a User.  Typically the validator will perform a number of "simple" checks (fields are not null, text fields are longer than 25 characters etc.).  The controller (for example) will then call the middle tier (userService.add(user)) and catch DuplicateKeyException (or a strongly typed DuplicateUserException) exception.  If this exception is thrown the controller will then populate the errors object and then re-display the form.

So what's wrong with that picture?  Quite simply the fact that some validation is now implicitly being done with the raising of the DuplicateKeyException indicating that validation has failed!.  The DB (in this example) is validating the data to ensure it is unique before inserting it, and if not it throws the exception.

My point (that I am admittedly being very verbose in making ;) ) is that this is all validation logic which belongs in the Validator.  Moving this uniqueness check into the validator where it belongs(!) enables a number of benefits:

  • It is a much cleaner, and more intuitive implementation; where do you look for validation logic?  In the validator.
  • The validator implementation is now truly re-usable.  Previously the validator was actually only validating some of the data.
  • Unit testing for a unique user is done within the validation unit tests.  This is much easier than unit testing the controller which would require mocking up an Errors, HttpServletRequest, HttpServletResponse (which is actually pretty easy, but still….) etc..  The number of objects that need to be mocked to test a validator is the Errors object, the DAO and your domain model.
  • The onSubmit method in the Controller now honours the contract specified by SimpleFormController (which states it is only called when validation succeeds), so the code is much cleaner.

This isn't rocket science, but a lot of people just don't "get" it.  I think it is probably because they view the validator as the place to validate that the request parameters are correct.  Sure you do that on the domain model itself, but that is still their mindset.  It isn't.  It is all about applying all your business validation rules.

Note: there is an argument that states you are repeating your validation logic; the DB knows what is and isn't unique, so why duplicate that logic in the controller?  Well, the point is that you *are* duplicating that logic, you are using the throwing of a DuplicateXXXException to indicate the validation failure, so this isn't really a valid argument.

There is also another argument that states that this isn't 100% guaranteed to catch *all* (in this case) duplicate keys.  And that is true.  There is a small window of opportunity after the validation has been called but before the middle tier call is made in which another process could sneak in and create the unique row, but this is a very *very* small window (typically milliseconds), and an OptimisticLockingException would probably thrown anyway.  Also consider the nature of the data.  It is highly unlikely that a single unique entitiy would be created by two different threads at the same time.  If it does happen, fine.  Let the exception trickle up to the container because it really is now an *exceptional* condition.

Rant over.

P.S.  The rest of my blog posts will probably be just as verbose :)

Similar Posts

Share this Post
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Slashdot
  • Technorati
  • TwitThis
 

39 responses


  1. Congrats Colin on joining I21!


  2. Hi Col, good to see you blogging again :-)

    Are you arguing that the middle tier userService should not attempt to validate the user? Or that it should, but it should re-use the same validator that the web tier should use?

    I'd be rather scared of a large-scale implementation where the middle-tier didn't validate stuff – what happens when someone adds a new controller (which maybe works somewhat differently) and forgets to re-use your validator?


  3. Hey Chris!

    I am not suggesting that UserService should, or shouldn't validate the user (although of course, your point is well made). I am suggesting that if you are going to have a validator, it should perform all the validation.

    In the example of Controllers, the validation belongs in the Validator, not the Controller. The middle tier is perfectly free to use the same validator as the controller *only if the validator performs all the logic*. If there are exceptional states (i.e. DuplicateKeyException) that can occur on the happy path, then re-using the validator is not enough; you also need to cope with the happy path exceptional state. If the validator does it's job well, then the DuplicateKeyException really is an exceptional condition.


  4. Validator is a good place for validation provided all my access to an application goes through a web layer (where Validator belongs).
    But what happens when I need access application remotely (RMI, JAX/RPC, any other web service) and I am not using Spring remoting. There are other remoting technologies like (Oh, my God!!!) EJB SLSB or MDB (Spring is perfectly OK under EJB facade)? Or Swing application access? Then what? No validation available as we do not hit web layer, i.e. Validator? No good…


  5. The Spring Validator is *completely* decoupled from the environment in which it is running. It has no dependencies on HttpServletRequest or HttpServletResponse etc.

    As Chris pointed out, validation is in no-way a web specific concept, and the Spring Validator framework does not artificially restrict you to only validating web requests. There is a very sophisticated binding process, which is utilised by Spring MVC to update your model from a HttpServletRequest, but this is completely decoupled from the Validation framework.


  6. So where it belongs then? To web layer, or service layer, or where?
    Say, in my application which is *.ear I have web.war, facade.jar, service.spring, domain.jar.
    Every jar is containing classes pertinent to a particular layer. Where (in which jar), in your view, Validator classes
    should be located in order to make validation available both in case when we have web layer and when we don't, i.e.no web.war in application.ear?


  7. Hi Colin,

    interesting write up.

    However, I have to admit I'm not confident about the fact that the validator should directly check a duplicated user.

    I'd make this kind of validation into the middle tier (your userService), eventually throwing an exception and *then* letting the Spring validator (*not* the MVC controller) dealing with it.

    What do you think?

    Cheers!

    Sergio B.


  8. Arno, the point I am making is that the validation can be in any tier, because the Spring validator is tier-agnostic.

    Sergio, there is no way that the validator has access to the exception thrown by the middle tier. The spring validator works on the basis that you "try, don't catch". In other words, you make sure the operation is going to succeed (i.e. the user isn't duplicate) via the validator and then try the operation. If the operation fails, it is an exceptional state. Of course, you don't have to do it this way, Spring gives you ultimate choice, but the validator should validate logic. A duplicate key is a validation error, so why shouldn't the validator check it :)


  9. [quote]the point I am making is that the validation can be in any tier, because the Spring validator is tier-agnostic.[/quote]
    Colin,
    Is there any code sample how to perform validation using Validation framework in application which does not have web layer? (no web.war, Spring MVC, Controllers, or any MVC to that matter)
    Validation on purely service layer.
    Can you share it?


  10. primary and foreign keys are for referencial integrity for database itself so that tables doesn't have ghost entries. Like many IT big guns says and we all learned from our experiences, DO NOT USE DATABASE FOR YOUR BUSINESS LOGIC. a duplicate user name should not occure that is a business decision and defined by Business and must be implemented in application. Let database do its own thing for its own good. Do not monkey with it. The reason to do so is, DBA might want to have a primary key on auto number column and not on field that you are trying to insert.


  11. [quote] Sergio, there is no way that the validator has access to the exception thrown by the middle tier.

    Sorry Colin, I didn't explain well.
    What I meant is: you can inject your middle tier service (userService) into the validator and let the validator call the userService for ensuring user uniqueness.
    I have to say I don't like this solution too much, but if you want to move all validation logic into the validator, what would you do?
    Like Arno says, maybe some code sample would help.

    However, too bad, I think that all that kind of validation logic strictly related to application use cases (creation of entities, performing of business operations) *doesn't* fit well into the validator.
    This is because you *cannot* separate the performing of business operations (in your example the creation of an User) from their validation (in your example the User uniqueness): this practice could lead to an incorrect domain state.
    Neither you can use the validator into your domain, because this would actually separate the two aspects above and couple the domain with external validation logic (I'm a DDD guy), nor you can use the validator into your middle tier, because if you call the validator into your middle tier for enforcing business logic, and *then* the same validator is called by the web controller, you get two calls for the same validator.

    Again, I think you should make some detailed example.

    My two euro cents.

    Cheers!

    Sergio B.


  12. One thing to also keep in mind is that validation and validation are 2. It often happens that the UI tier needs specific implementations of the validation logic, e.g. very fine grained validation to have very specific error messages, or specific sequencing in the validation because of sequencing of fields on pages (i.e. in a flow).

    So in non trivial situations I don't have any problem writing 2 validators: 1 that does the big bang validation in the 'business tier', and a UI specific validator used by specific controllers. The 'business tier' validator always runs when data moves into the service layer, regardless of any validation done in the UI layer.

    Another thing I would like to add is that your write-up seems a bit black-and-white. Instead of blindly putting validation logic in the 'Validator', I would just advice people to factor their validation logic into those components where it fits most naturally, e.g. taking granularity and reuse into account. I.e. fit your validation into the overall design of your domain layer since its obviously an integral part of it.


  13. Hey all,

    This thread is generating some really interesting comments. Good discussion!

    There seems to be some confusion as to what I am actually suggesting, so let's take this down to a simple use case (which I maybe should have done before). That of adding a new User. I have *some validation logic*, somewhere (be it in an explicit Validator, or in the domain model itself, that is irrelevant). The point The thing I would advise people is to identify *all* the rules that define *valid* data, and the uniqueness of that data is just as much a validation rule as saying the username must not be null. That is the only point I am trying to make here :)

    Stating that that isn't a validation rule, but then catching a DuplicateKeyException and displaying an error "please enter a unique username" just doesn't cut it for me.

    I really don't want to get down into whether this validation should be applied at web layer, or middle layer, or both etc. I am simply suggesting that people stop and think carefully about what the validation rules are, and then make sure that they are explicitly, and consistently enforced.

    Sergio; I take it as a DDD guy you are objecting to the seperation of validation logic from the domain model itself. Fine. I take no issue with that, if the User itself knows what a valid user is, then the same applies. It is all about the *definition* of a valid user, and uniqueness is part of that definition.

    BTW; I would probably *not* use the User to represent a new User anyway, I would probably have a strongly typed RequestToCreateUser simply because the creation of a new user requires a different data set to the domain model User (password/confirmPassword versus user.isPasswordCorrect etc.) but that is a different blog :)

    I am also trying not to have to resort to code samples because that would require too many decisions to be made (where is validation applied etc.), and the point I am making is more general than that.

    It simply boils down to this; identify *all* the validation logic and then apply it in a single coherent, atomic, explicit operation. Validators are powerful things, they can do more than just the *syntax* of the data, they can, and should also check the *semantics* of the data :)


  14. [quote] The thing I would advise people is to identify *all* the rules that define *valid* data [/quote]

    Colin, maybe there's a little misunderstanding, as pointed out in my quote.
    If we talk about *valid* data, user uniqueness can be considered so and I could agree with you: the Validator must check that the data is valid, and user uniqueness can be such a validation rule.
    However, there are a lot of business rules that cannot be applied in Validators: i.e., in a funds transfer use case for a banking application, the validity of a money amount *must* be checked in the domain layer.

    [quote] I would probably *not* use the User to represent a new User anyway, I would probably have a strongly typed RequestToCreateUser simply because the creation of a new user requires a different data set to the domain model User (password/confirmPassword versus user.isPasswordCorrect etc.) but that is a different blog [/quote]

    I disagree: frameworks like Spring and Hibernate are so good also because they enable us to use rich domain models through all application layers … however, yes, this is another story!

    Good discussion.

    Cheers!

    Sergio B.


  15. Sergio;

    However, there are a lot of business rules that cannot be applied in Validators: i.e., in a funds transfer use case for a banking application, the validity of a money amount *must* be checked in the domain layer.

    This is an interesting one. Of course account.withdraw(10) should throw InsufficientFundsException, but do you not think the validator should also verify that account.withdraw(10) would succeed (account.getFunds()>10, or account.canWithdraw(10) == true)? I do.


    I disagree: frameworks like Spring and Hibernate are so good also because they enable us to use rich domain models through all application layers … however, yes, this is another story!

    I absolutely, unequivacally, 100%, without reservation agree with you :) .

    But I don't think that answered my question. To create a new user, you need to specify a password and a confirm password.

    A User should *never* expose a getPassword(), rather, a rich domain model that followed good OO should also follow encapsulation and therefore contain a user.isPasswordValid(proposedPassword).

    If you are proposing that the User *does* contain a get/setPassword and get/setConfirmPassword then surely you are actually going down the anaemic domain model; the exact antithesis of DDD.

    This is another story, and maybe I will blog about it sooner rather than later. We are both agreeing on the end goal (rich domain models), but yet we both seem to discredit each others approach :)

    I love these discussions! As a fellow colleague of mine would say "Rock on!"


  16. Collin,
    I think a sample piece of code would do even if you think it would lead to too many decisions. But overall a good discussion!!


  17. [quote] Of course account.withdraw(10) should throw InsufficientFundsException, but do you not think the validator should also verify that account.withdraw(10) would succeed (account.getFunds()>10, or account.canWithdraw(10) == true)? I do. [/quote]

    Colin, I don't think so: I don't see any value added in verifying this rule *also* in a Validator.

    [quote] To create a new user, you need to specify a password and a confirm password.
    A User should *never* expose a getPassword(), rather, a rich domain model that followed good OO should also follow encapsulation and therefore contain a user.isPasswordValid(proposedPassword).
    If you are proposing that the User *does* contain a get/setPassword and get/setConfirmPassword then surely you are actually going down the anaemic domain model; the exact antithesis of DDD. [/quote]

    I fully agree with you, and if you read my blog you can understand my way of thinking.
    I think getters/setters should be avoided as much as possible, but I don't like those kind of DTOs like your RequestToCreateUser: I prefer a lot to use rich domain objects, eventually decorating/adapting them with additional getters/setters (like your get/setPassword and get/setConfirmPassword) using AOP introductions.
    Shameless plug: I'm a Spring Modules developer and founder of the XT Framework module, containing, among other things, also an implementation of such a thing, based on Spring AOP.
    However, this is off-topic and would deserve a whole post on its own.

    [quote] We are both agreeing on the end goal (rich domain models), but yet we both seem to discredit each others approach [/quote]

    I don't think we are discrediting anything: we have different approaches, which is a good thing.
    If everyone had the same approaches and ideas, there would be no discussion, and so no further learning … don't you think?

    So yeah, rock on!

    Cheers!

    Sergio B.


  18. [quote] Of course account.withdraw(10) should throw InsufficientFundsException, but do you not think the validator should also verify that account.withdraw(10) would succeed (account.getFunds()>10, or account.canWithdraw(10) == true)? I do. [/quote]

    Colin, I don't think so: I don't see any value added in verifying this rule *also* in a Validator.

    [quote] To create a new user, you need to specify a password and a confirm password.
    A User should *never* expose a getPassword(), rather, a rich domain model that followed good OO should also follow encapsulation and therefore contain a user.isPasswordValid(proposedPassword).
    If you are proposing that the User *does* contain a get/setPassword and get/setConfirmPassword then surely you are actually going down the anaemic domain model; the exact antithesis of DDD. [/quote]

    I fully agree with you, and if you read my blog you can understand my way of thinking. ;-)
    I think getters/setters should be avoided as much as possible, but I don't like those kind of DTOs like your RequestToCreateUser: I prefer a lot to use rich domain objects, eventually decorating/adapting them with additional getters/setters (like your get/setPassword and get/setConfirmPassword) using AOP introductions.
    Shameless plug: I'm a Spring Modules developer and founder of the XT Framework module, containing, among other things, also an implementation of such a thing, based on Spring AOP.
    However, this is off-topic and would deserve a whole post on its own.

    [quote] We are both agreeing on the end goal (rich domain models), but yet we both seem to discredit each others approach [/quote]

    I don't think we are discrediting anything: we have different approaches, which is a good thing.
    If everyone had the same approaches and ideas, there would be no discussion, and so no further learning … don't you think? ;-)

    So yeah, rock on!

    Cheers!

    Sergio B.


  19. Quick reply….somebody contacted me stating that their comments were marked as spam. This is not intentional, and certainly not my opinion….I think all the replies are useful.

    So apologies if you are marked as spam….I will try and sort it out to prevent this in the future.


  20. Hi Colin,

    Nice thread you started. And congrats on your new job/blog. :)

    I like the general idea of "doing all the validation in validators". :)

    On the other hand, I do have a practical concern in the context of implementing this with OSIV hibernate in place. If we inject a service API into a validator to, say, check the uniqueness of a user name, chances are this user name comes from a domain object. This domain object would usually be loaded through a thread-bound session and bound to request parameters, i.e., has become dirty by the time it reaches the validator. So when the service call is made, even though it is a read-only transaction, hibernate _might_ decide to flush the session and, well, cause the very constraint violation exception we are trying to avoid.

    Just my 2 cents.
    Cheers.
    –Jing


  21. Hi Colin,

    I just want to make sure I've got what you're saying. So thinking about the implementation, you would have a UserValidator that might be injected with a UserService (or whatever provides a username lookup) to do lookup of the username like so:

    public void validate(Object obj, Errors errors) {
    User validatingUser = (User) obj;

    // username validation
    ValidationUtils.rejectIfEmpty(errors, "username", "error.required");

    if (userService.isUsernameExists(validatingUser.getUsername())) {
    errors.rejectValue("username", "error.user.exists",
    new Object[] { new DefaultMessageSourceResolvable("username") },
    "Username already in use");
    }
    }

    public void setUserService(UserService us) { ….. }

    By the way, congrats on joining Interface 21.

    Brendan


  22. P.S. Obviously what I quickly tapped up there would only be work for validating new user creations, but that's the C- version…


  23. [quote comment=\"101\"]Hi Colin,

    Nice thread you started. And congrats on your new job/blog. :)

    I like the general idea of \"doing all the validation in validators\". :)

    On the other hand, I do have a practical concern in the context of implementing this with OSIV

    hibernate in place. If we inject a service API into a validator to, say, check the uniqueness of a user name, chances are this user name comes from a domain object. This domain object would usually be loaded through a thread-bound session and bound to request parameters, i.e., has become dirty by the time it reaches the validator. So when the service call is made, even though it is a read-only transaction, hibernate _might_ decide to flush the session and, well, cause the very constraint violation exception we are trying to avoid.

    Just my 2 cents.
    Cheers.
    –Jing[/quote]

    Jing; The problem you describe with OSIV is a real one. However, the calling to a middle tier service, even if it is transactional will not make it any worse, because Hibernate will already think it is dirty. Indeed, if validation fails (regardless of what the validator does) then you need to take care of marking the current transaction (if any) as read only, or evict the object from the session etc.

    The other comment is that the kind of things I am talking about (in particular checking the uniquess when creating a new user) would not require the use of hibernate; or would certainly not require the use of hibernate to persist the object, mere lookups would be sufficient.


  24. [quote comment=\"102\"]Hi Colin,

    I just want to make sure I\'ve got what you\'re saying. So thinking about the implementation, you would have a UserValidator that might be injected with a UserService (or whatever provides a username lookup) to do lookup of the username like so:

    public void validate(Object obj, Errors errors) {

    User validatingUser = (User) obj;

    // username validation

    ValidationUtils.rejectIfEmpty(errors, \"username\", \"error.required\");

    if (userService.isUsernameExists(validatingUser.getUsername())) {

    errors.rejectValue(\"username\", \"error.user.exists\",

    new Object[] { new DefaultMessageSourceResolvable(\"username\") },

    \"Username already in use\");

    }
    }

    public void setUserService(UserService us) { ….. }

    By the way, congrats on joining Interface 21.

    Brendan[/quote]

    Brendan; yes, that is the kind of thing I am suggesting :)

    I keep meaning to produce a quick code sample, but with a 13 week old baby I have *no* time to do anything :)


  25. I've just linked to this post from my blog as part of Blog Surprise and BlogDay fun. Thanks for being an unwitting participant :) . Nice design here – I'm intrigued at how well you and your team have constructed this thing.


  26. [quote comment=\"123\"]I\'ve just linked to this post from my blog as part of Blog Surprise and BlogDay fun. Thanks for being an unwitting participant :) . Nice design here – I\'m intrigued at how well you and your team have constructed this thing.[/quote]

    I find myself quite often being an \"unwitting participant\" :)

    \"Intriqued\" is an interesting word ;) If I can clarify any aspects, please ask.


  27. Hello Collin,

    just thee questions on your discussion:

    1. As you suggest to have one single validator class for one business object and want to have uniqueness being checked, how do you distinguish between objects that are being created and those who are being edited. If you check an user being edited for a unique username you of course will find "another" one in the database, which is absolutely correct because its the object to be edited.

    2. Could you give some heuristics or starting points where to place validation logic calls in layers? What is actually obvious is validating objects in contolles at web layer. Validating at service methods that receive objects to be worked with might be a good guideline but that would actually scatter validation calling code through the first lines of those service methods. Maybe AOP could help there?

    3. What still is not clear to my mind is the programming model of the validator if not used in controllers (where you actually don't have to directly call or access them). I actually also couldn't find any examples except the ones were validators are used in contollers that provide some kind of best practise of how to use them. Also the Javadoc is not really useful there, like it is while programming SimpleFormControllers e.g.

    Thanks in advance,
    Ollie


  28. [quote comment="200"]1. As you suggest to have one single validator class for one business object and want to have uniqueness being checked, how do you distinguish between objects that are being created and those who are being edited. If you check an user being edited for a unique username you of course will find "another" one in the database, which is absolutely correct because its the object to be edited.
    [/quote]
    This is an excellent question, and is another rational for having seperate "RequestTo" objects, i.e. a RequestToCreateUser and a RequestToEditUser.

    If we agree that the uniqueness of the user is part of the validation rules, then I am happy :) Discussing the best way of *implementing* that is a whole other topic ;)

    [quote comment="200"]
    2. Could you give some heuristics or starting points where to place validation logic calls in layers? What is actually obvious is validating objects in contolles at web layer. Validating at service methods that receive objects to be worked with might be a good guideline but that would actually scatter validation calling code through the first lines of those service methods. Maybe AOP could help there?
    [/quote]
    This is almost going to start a religous war, but I think it absolutely depends on where your "layer of trust" is. If you are writing a module which can be called by people outside of your control then that module absolutely must do it's own validation. If you do decide to validate data in the middle tier then fine, if you don't fine….as long as it is documented. I am generally responsible for all layers within applications that I have worked on, so I do the validation at the top tier (controllers, web services etc.) and not at the middle tier. Simply because this is good enough and there are excellent infrastructure for doing so (in Spring MVC/Spring Web Flow).

    Let the flames begin :)

    [quote comment="200"]
    3. What still is not clear to my mind is the programming model of the validator if not used in controllers (where you actually don't have to directly call or access them). I actually also couldn't find any examples except the ones were validators are used in contollers that provide some kind of best practise of how to use them. Also the Javadoc is not really useful there, like it is while programming SimpleFormControllers e.g.[/quote]
    If you have ever unit tested a validator; which I sincerely hope we all do :) then you will understand how easy it is to create them. You simply new up the validator (or use the DI one because validators are usually stateless), new up an implementation of the Errors object, call the validator and then check to see if there are any errors.


  29. Just a question here: if you have a UserValidator to ensure that a username is unique, how do you know the context?

    IE, if I want to validate a User upon insert, its not ok to have a duplicate, but if its an update, I cant follow the same validation logic?

    BTW, we are using the validator not against forms, but in our application layer


  30. How does your validator know if the user is being inserted vs updated?


  31. How does your validator know if its an insert operation or an update operation?

    If its an insert, I can see how you can detect the duplicate, but an update shouldnt have the same case.


  32. [quote comment="287"]How does your validator know if its an insert operation or an update operation?

    If its an insert, I can see how you can detect the duplicate, but an update shouldnt have the same case.[/quote]
    Why not have two validators? Of course, the second one (with the additional uniqueness check) should extends the other one (which checks all the other properties).

    Alternatively you could do something clever with checking the combination of the uniqueId and username (where table.id != uniqueId) etc.


  33. Hi Colin,

    with all the information in this blog (thx all), i have now implement the folowing design and i hope it is useful for anyone. The example checks if one name is already exists (insert & update) in the database.

    public class LandValidator implements Validator{
    private ValidationManager validationManager;
    public ValidationManager getValidationManager() {
    return validationManager; }
    public void setValidationManager(ValidationManager validationManager) {
    this.validationManager = validationManager; }

    public boolean supports(Class clazz) {
    return Land.class.isAssignableFrom(clazz); }

    public void validate(Object obj, Errors errors) {
    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "NAME_REQUIRED", "Name Required.");
    if (errors.getErrorCount() == 0) {
    boolean chkConstraint = validationManager.chkLandNameExists((Land)obj);
    if (chkConstraint) {
    errors.reject("NAME_ALREADY_EXISTS", "The Name already exists.");
    }
    }
    }
    }
    The Validator call the service layer Validator Manager Interface. The implemantation is like:
    public class ValidationManagerImpl implements ValidationManager{
    private LandDAO landDAO;
    public LandDAO getLandDAO() {
    return landDAO; }
    public void setLandDAO(LandDAO landDAO) {
    this.landDAO = landDAO; }

    public boolean chkLandNameExists(Land land) throws RuntimeException {
    return landDAO.chkLandNameExists(land);
    }
    }
    Last the Implementation of the DAO:
    class LandDAOImpl extends HibernateDaoSupport implements LandDAO{

    public boolean chkLandNameExists(Land land) throws RuntimeException {
    List tmpList = getHibernateTemplate().find("from Land l where l.name=?", land.getName());
    if (tmpList.isEmpty()) {
    return false;
    } else if (carrier.getId() == null) {
    return true;
    } else {
    for (Iterator it = tmpList.iterator();it.hasNext();){
    Land tmpLand = (Land)it.next();
    if (!tmpLand.getId().equals(land.getId()))
    return true;
    }
    }
    return false;
    }
    }

    I hope there is no typing error in my example.

    Thx for all information
    Michael


  34. first correction:
    carrier.getId() is certainly land.getId()


  35. I did make a education on the topic of "Web Application Security" recently.

    Of course, Input Validation was a big topic itself. I did suggest 2 approaches:
    * either do the validation within the domain object itself
    * use a validation framework (I did of course mention the Spring validation stuff)

    Now both appeal to me. I did see some arguments for the validation within the domain object itself
    * the domain object would be "secure by default"
    * the validation would be baked-in

    The main disadvantage seems to be the fact that you cannot change the validation rules (i.e. the validator implementation). You could do this by informing the domain object about the current context it is in (e.g. in web context, where the users' address simply has to make sense, and the business logic layer, where the address has to be checked against a directory of sorts)

    What are your opinions on the issue of validation done inside vs. outside of a domain object?

    btw: it's great to hear that I am not the only one concerned with this issue. And it's great to hear that interface21 (or whatever its called now) is taking it seriously. Go on with the verbosity level, it's appreciated…


  36. Hi All,

    I have below validator class which implements Validator interface but can't test the code because I don't know how to map with which mapping xml.Please any help urgent.

    public class CarValidator implements Validator{

    private static Log log = LogFactory.getLog(CarValidator.class);

    public boolean supports(Class clazz) {
    return clazz.equals(Car.class);

    }

    public void validate(Object car, Errors errors) {
    log.debug("Begin CarYearValidator validation.");

    // carMake must be set
    ValidationUtils.rejectIfEmpty(errors, "carMake", "carMake.empty");

    /* String carMake = ((Car)car).getCarMake();
    if (carMake == null || carMake.length() >= 1){
    errors.reject("car_make_length", new Object[] {new Integer(1)}, "car make must be shorter" );
    }
    */

    log.debug("End CarYearValidator validation.");
    }

    }


  37. Just ran into this thread. The original post is somewhat presumptuous, besides being rather arrogant:

    >> but this is a very *very* small window (typically milliseconds),
    How's milliseconds a very small window? Sounds as big as any. If transactional integrity is violated, it doesn't matter what the window is. If it can happen – it will happen.

    >> and an OptimisticLockingException would probably thrown anyway
    Optimistic locking is performed for existing objects. The original question, I believe, comes from inserting a new record, i.e. optimistic locking exception will not be thrown away.


  38. gbhkiv nlerh dkjmn zusbjhr ajgirdnwo tbfwxyok trpjcmeu


  39. silly question:

    if I create a class that extends validator, how do I call the validate(Object, Errors) from by service layer method? Actually, how to I instantiate an Errors implementation? in spring mvc, spring is doing this automatically.

    Thank you.

One trackback

Leave a Reply