Results 1 to 10 of 10

Thread: Validation of Data Uniqueness Constraints

  1. #1
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default Validation of Data Uniqueness Constraints

    This is an offshoot of a previous thread. My question pertains to whether in practice people validate their data prior to attempting to insert the data when there are business uniqueness constraints on some of the data.

    Here is an example: let's assume that we have a User entity:
    Code:
    package org.spring.forum;
    
    public class User {
    
        private String identifier;
        private String username;
        private String emailAddress;
        private String phoneNumber;
        
        public String getIdentifier() {
            return this.identifier;
        }
        
        public void setIdentifier(String identifier) {
            this.identifier = identifier;
        }
        
        public String getUsername() {
            return this.username;
        }
        
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getEmailAddress() {
            return this.emailAddress;
        }
        
        public void setEmailAddress(String emailAddress) {
            this.emailAddress = emailAddress;
        }
        
        public String getPhoneNumber() {
            return this.phoneNumber;
        }
        
        public void setPhoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
        }
    
    }
    Please forgive me for making all of these attributes plain Strings, but this is just for demonstration purposes.

    Now assume that this class maps to a USER database table defined as:
    Code:
    USER table
    identifier [primary key]
    username [unique, not null]
    emailAddress [unique, not null]
    phoneNumber
    Let's also assume that we are using Hibernate and using a HibernateUserDao class to persist a user:

    Code:
    public class HibernateUserDao extends HibernateDaoSupport implements UserDao {
    
       public void saveUser(User user) {
          getHibernateTemplate().save(user);
       }
    
    }
    Lastly, let's assume that there is a UserManager class that uses the UserDao:
    Code:
    public class UserManagerImpl implements UserManager {
       
       private UserDao userDao;
    
       public void setUserDao(UserDao userDao) {
          this.userDao = userDao;
       }
    
       public void createNewUser(String username, String emailAddress, String phoneNumber) {
          User user = new User();
          user.setUsername(username);
          user.setEmailAddress(emailAddress);
          user.setPhoneNumber(phoneNumber);
          
          this.userDao.saveUser(user);
       }
    }
    Now the question is: should validation be performed to ensure that neither the username nor emailAddress of the new user is already found in the database? I realize that a DataIntegrityViolationException can be caught after trying to persist the new user (although there are other persistence-related issues involving that, which were brought up in the previous thread). But how could the UserManagerImpl class present the user with a user-friendly error message if that approach is taken?

    At the other end of the spectrum, validation could make several different database calls, such as "select count(*) from USER where username = ?", username to ensure that the fields are unique prior to persisting the new user. In that case, a special error message can be presented to the user depending on which field(s) were found to already exist. Is that the only meaningful way to approach such validation? I only ask because unique constraints are a very common type, and yet I have never seen examples where people actually perform this validation in Java code. Is that just because all sample applications are so simplistic in nature?

    Any input would be appreciated. Am I missing how to effectively use the DataAccessException hierarchy?

    A second issue is: if uniqueness validation is performed prior to the attempted save operation, it could still fail because of a unique constraint violation during the save (maybe a User with that username was inserted after the validation but before the save). I would think that it would be okay in this rare case to give a less informative error message, as it might not be obvious which is the offending field(s). At least subsequent attempts to persist the user would return with more informative error messages (because validation would find the duplicates rather than the data being passed to the database).

    So what is the standard practice?

    -Arthur Loder

  2. #2
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default Relevant Blog Posting

    In addition, Colin Yates (yatesco) posted this blog entry regarding Java-side validation of data.

    -Arthur Loder

  3. #3

    Default

    Honestly I wouldn't mind making few(?) database call to make sure my data is fine which also include some kind of application specific rules around it. Reason? first and foremost is I really am not interested in mapping my database vendor error codes with my application ones. I really don't have to compare error messages and/or error codes and do some kind of interpretation of them, To me a SQL exception is a sql exception and should be expected in certain scenario. and my application must know that data is good way before this sql exception is thrown. Just imagine even if DataAccessException was to give you error code and message it still would be code and message string that you will be mapping to your custom messages and codes.

  4. #4
    Join Date
    Dec 2005
    Location
    U-241
    Posts
    237

    Default

    I do mind. I do not like an idea that in order to insert 10 users I have to make at least 20 roundtrips to database. This is questionable in web-only environment and wacky when one need to implement remote/Swing access. Every single JAX/RPC call is way too expensive.

    In my view 'check first','insert next' approach does not fit in an environment where we might have triggers generating calls to multiple stored procedures. How can you possibly check unless you duplicate in Java validation logic already embedded in PL/SQL. I wish I could follow 'DO NOT USE DATABASE FOR YOUR BUSINESS LOGIC' but it is only at home I have a luxury to create my own database. In real projects DB is usually 'a given reality' either legacy or created by guys called DBA team who could not care less about Java. Instead they rely on stored procedures and try to argue with them whether their PL/SQL logic relates to persistence or business. Fat chance. I do not like the idea of double-validation - first by Java and then by stored procedures anyway. Why doing the same check twice? Like they say 'triggers and ORM are often a problematic situation'. Hit the trigger and let the user bite the bullet.

    I only ask because unique constraints are a very common type, and yet I have never seen examples where people actually perform this validation in Java code. Is that just because all sample applications are so simplistic in nature?
    Aren't we playing ostrich here?...
    Spring, it's a wonderful thing...

  5. #5
    Join Date
    Jun 2005
    Posts
    4,230

    Default

    I don't have any particular design for Validator implementation right now, but I think I have to agree with both sides of this argument. I sympathise with Arno about the lack of control that we sometimes have over the database design and implementation, but I shudder to think of complicated business logic validation being done in PL/SQL. How is it tested? That makes me wish that all my validation could go in one re-usable place on the Java side.

    On the other hand, there may be a valid performance concern with hitting the database too many times during validation. If the logic is complex, then there may be no practical alternative, and we have to take the hit. But, maybe something as simple as a uniqueness constraint actually could be a special case. The RDBMS does this one natively, with no intervention from DBA-programmer, and it is going to be way more efficient at doing it than we are.

    Maybe there's no point being too pure about this. After all, the RDBMS will handle not-null constraint natively too, but we can do that very cheaply in Java, and so we should. And test it thoroughly.

  6. #6

    Default

    Quote Originally Posted by Arno Werr
    I do mind. I do not like an idea that in order to insert 10 users I have to make at least 20 roundtrips to database. This is questionable in web-only environment and wacky when one need to implement remote/Swing access. Every single JAX/RPC call is way too expensive.
    so is Database IO.
    In my view 'check first','insert next' approach does not fit in an environment where we might have triggers generating calls to multiple stored procedures.
    when you say "we might have triggers calling multiple stored procedures ......." you mean not for inserting a duplicate user is that right? if not than there is something really serious with your database design.
    How can you possibly check unless you duplicate in Java validation logic already embedded in PL/SQL.
    PL/SQL? why would you want such a simple statement like "select count(*) from users where user_id = ?" in PL/SQL? another thing you are making an assumption that your table's constraint is defined on user_id column, like I said DBA's might want to have a PK on an identity column with incremental numbers. in that case you will write small PL/SQL to raise an error from database.
    I wish I could follow 'DO NOT USE DATABASE FOR YOUR BUSINESS LOGIC' but it is only at home I have a luxury to create my own database. In real projects DB is usually 'a given reality' either legacy or created by guys called DBA team who could not care less about Java. Instead they rely on stored procedures and try to argue with them whether their PL/SQL logic relates to persistence or business. Fat chance. I do not like the idea of double-validation - first by Java and then by stored procedures anyway. Why doing the same check twice? Like they say 'triggers and ORM are often a problematic situation'. Hit the trigger and let the user bite the bullet.
    So let me get this straight, your java application is pretty much like a thin middle layer (or a deligator rather?) with thin client and thick server. Am I getting it right? hummmm in that case you need to write client/server app and not distributed one. there is no point about using spring framework or any other kind of frameworks or not even any kind of design pattern as there is not much of a maintenence on java side. you just interact with your database directly from your jsp and be done with it. All you need is jsps and persistance code and you are done. Can't be more simpler than this.
    Last edited by tatvamasi; Aug 28th, 2006 at 08:35 AM.

  7. #7
    Join Date
    Dec 2005
    Location
    U-241
    Posts
    237

    Default

    so is Database IO.
    Are you saying now that
    making few(?) database call to make sure my data is fine
    is not such a great idea? I would agree with you on this account.

    when you say "we might have triggers calling multiple stored procedures ......." you mean not for inserting a duplicate user is that right? if not than there is something really serious with your database design.
    Please, do not try to simplify things. I am talking here about complex scenarios where in order to insert/update a record a trigger will generate calls to multiple stored procedures. There are potentially 16 levels of nesting. If you do not like this reality you may a) continue playing ostrich b) please, feel free to persuaded DB vendors to remove procedure nesting from their products. But as long as PL/SQL/TransactSQL with all their power are there to stay, DBA guys will use them and I have to deal with them. I wish I could practice Uncle Joe Convenience Store web site development.

    So let me get this straight, your java application is pretty much like a thin middle layer (or a deligator rather?) with thin client and thick server. Am I getting it right?
    Not really. There's a lot more in enterprise Java then just hitting a database. And thank you for an advice of interacting 'with your database directly from your jsp'. Thanks, but no, thanks...
    Spring, it's a wonderful thing...

  8. #8

    Default

    [QUOTE=Arno Werr]Are you saying now that is not such a great idea? I would agree with you on this account.

    Please, do not try to simplify things. I am talking here about complex scenarios where in order to insert/update a record a trigger will generate calls to multiple stored procedures. There are potentially 16 levels of nesting. If you do not like this reality you may a) continue playing ostrich b) please, feel free to persuaded DB vendors to remove procedure nesting from their products. But as long as PL/SQL/TransactSQL with all their power are there to stay, DBA guys will use them and I have to deal with them. I wish I could practice Uncle Joe Convenience Store web site development.
    blah blah blah......... you can go on......
    Not really. There's a lot more in enterprise Java then just hitting a database. And thank you for an advice of interacting 'with your database directly from your jsp'. Thanks, but no, thanks...
    Exactly and thats why you need a middle layer business components implementing business rules so it could be called from anywhere and your business layer stays same. well blah blah blah I could go on too...... ha hah ha I am glad that you grown out the shadow of Rod Johnson. ha ha ha

  9. #9
    Join Date
    Dec 2005
    Location
    U-241
    Posts
    237

    Default

    Oh my, we've found something to agree upon, tatvamasi. Yet, on the second thought, I'd rather enjoy the shadow. It's August out there and his name is easy to handle.
    Spring, it's a wonderful thing...

  10. #10
    Join Date
    Sep 2006
    Posts
    1

    Smile Unique Key constraint

    hi all,

    I faced the same problem in my application and i maked an sql call to find bypass the error.But i'm not happy with my approach.So we thought of creating a framework which stores those UK constraints which can be validate all data operations automatically.Some of you are not happy with having database call to check unique key constraint,but this cannot be avoided in any case as we are validating against existing data.If any one finds some new approach i'm haapy to discuss on that

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •