ADF and alternate unique keys revisited
By Lukasz Romaszewski on Apr 07, 2014
Today I'd like to share a quick (and dirty) trick to handle one nuisance of well known pattern to achieve uniqueness of "non-primary key" ADFBC entity attributes. If you ever needed to enforce a particular attribute to contain globally unique values you may end up with two solutions:
1. Check it on the db site and then handle the unique constraint violation exception in DCExceptionHandler replacing dirty SQL message with a pretty one that you provide
2. Try to catch it before it even reaches DB and handle it in a nice way using entity validation messages
Obviously the second approach seems to be much better from both architectural and practical point of view (let alone the fact that it does not rule out using the former one at the same time!).
To implement the second approach we can use alternate key mechanism - you may find detailed descriptions here and here. However, there is one little inconvenience: if you try to enter a non unique value for a mandatory attribute protected by alternate key uniqueness (especially if you do it in a completely new row, not posted to the db yet) you will actually see two errors:
The first one will be the right one stating the value is not unique. The second one is quite surprising - it will complain that this mandatory attribute is empty! The reason for this behavior is a bit complex to explain, but to simplify: first exception is caught during a JSF Update Model phase (setting the attribute) which in fact clears the value of the attribute to the default one (empty), the second during ADF Validate Model Update (validating the transaction).
To get rid of the second exception you may set the SkipValidation property to true on the proper page definition which disables the entity and transaction level validations for this particular page:
Now if you enter a non-unique value you will see only the first message:
To illustrate the technique I have uploaded a simple HR schema based application (developed with JDeveloper 12c), you can find it here.
Please be aware that it will disable all other validations apart from those defined on attribute level, so that's why I would call this solution a bit quick and dirty :)