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:
Please forgive me for making all of these attributes plain Strings, but this is just for demonstration purposes.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; } }
Now assume that this class maps to a USER database table defined as:
Let's also assume that we are using Hibernate and using a HibernateUserDao class to persist a user:Code:USER table identifier [primary key] username [unique, not null] emailAddress [unique, not null] phoneNumber
Lastly, let's assume that there is a UserManager class that uses the UserDao:Code:public class HibernateUserDao extends HibernateDaoSupport implements UserDao { public void saveUser(User user) { getHibernateTemplate().save(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?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); } }
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


Reply With Quote