Greetings,
ADF BC (Business Components) allows you to write code declaratively instead of writing spaghetti code in Java.
One of the feature is Alternate key constraint which is different from Primary and Unique key constraints available in database. Usually Primary key values are coming from database sequence so you don't have to worry about their uniqueness but if you like to validate uniqueness on other columns e.g. email address,Region or Country Name that's where Alternate key comes into action.
Following are some properties of alternate keys:
Lets look into example (Download the complete example)
Use case:
Database schema: HR @ Oracle XE
Column Country name must be unique in Countries table. We have primary key CountryId in the table as shown in the slide
Solution:
Creating Alternate Key:
Right click the Entity Object and Choose "New Entity Constraint"
Enter the name of the constraint, Enter the Attribute where you want to add constraint in our case select Country Name
You can verify the Alternate key constraint Under general tab of entity object properties
Creating Unique Validation:
Go to Business Rules tab in Entity Object properties and Click Create New Validation by selecting "Entity Validators" as shown in the slide
Select "Unique Key" from Rule Type list. Select the Alternate key constraint from Keys
Go to Failure tab and Enter custom error message
Run the Application Module, Create new Record and Enter Unique country name like Brazil, You would see the similar error message.
Also on JSF page you would see error message on Commit
Happy JDeveloping,
Zeeshan Baig
ADF BC (Business Components) allows you to write code declaratively instead of writing spaghetti code in Java.
One of the feature is Alternate key constraint which is different from Primary and Unique key constraints available in database. Usually Primary key values are coming from database sequence so you don't have to worry about their uniqueness but if you like to validate uniqueness on other columns e.g. email address,Region or Country Name that's where Alternate key comes into action.
Following are some properties of alternate keys:
- You can check Uniqueness at record level e.g. Department Name must be unique
- You can have many alternate keys as compare to Primary keys
- You can look for a row in entity object using findByKey() method
- If the key is found in entity objects ADF will throw TooManyObjectsException
Lets look into example (Download the complete example)
Use case:
Database schema: HR @ Oracle XE
Column Country name must be unique in Countries table. We have primary key CountryId in the table as shown in the slide
Solution:
- Create an Alternate key constraint on Entity object.
- Add Unique Key validation on Entity Object using alternate Key
Creating Alternate Key:
Right click the Entity Object and Choose "New Entity Constraint"
Enter the name of the constraint, Enter the Attribute where you want to add constraint in our case select Country Name
You can verify the Alternate key constraint Under general tab of entity object properties
Creating Unique Validation:
Go to Business Rules tab in Entity Object properties and Click Create New Validation by selecting "Entity Validators" as shown in the slide
Select "Unique Key" from Rule Type list. Select the Alternate key constraint from Keys
Go to Failure tab and Enter custom error message
Run the Application Module, Create new Record and Enter Unique country name like Brazil, You would see the similar error message.
Also on JSF page you would see error message on Commit
Happy JDeveloping,
Zeeshan Baig
LinkedIn: http://www.linkedin.com/in/baigzeeshan
Very Interesting !! It really helped me a lot!!
ReplyDeleteThanks Baig but there is a problem,
ReplyDeleteIf you make country name not mandatory
and inserted empty country name and press commit.
if you tried to update country name to an existing name for example France, the unique constraint will not fire.
I don't know if this is ADF bug or what.
Hi,
ReplyDeleteI am having a use case in which I need to call alternate key validation during inserting a row into VO through a button call. In this scenario how we can call the EO validator?. EO validator works fine at the time of commit but my use case is not to commit...Please advise.
Thanks,
Alok
You can call ValidateEntity() method of Entity. Check this link for more info http://docs.oracle.com/cd/B14099_19/web.1012/b14022/oracle/jbo/server/EntityImpl.html#validateEntity__
DeleteZB
Hi Zeeshan,
ReplyDeleteWhen u select an alternate key in property inspector in other tab u get an option of Primary Key as true or false.
What exactly does this Primary Key reflects, and how does it effects the working.
Hi Zeeshan,
ReplyDeleteI have a doubt related the format of the message displayed.
Your example in jsf page display "Please enter unique country name" and in the Application Module it displays "JBO-com.baigzeeshan.alternateKey.model.Countries_Rule_0: Please entery unqiue Country Name".
My doubt is because I have done something similar but on JSF page displays exactly the same error as in the Application Module, I mean, it also displays the JBO part. Is there a way to get rid of the JBO part for the JSF page?
Hi,
DeleteYou can customized the database error messages check this http://docs.oracle.com/cd/E24382_01/web.1112/e16182/validation_model.htm#BEIJJDEC
Zeeshan
Thanks for sharing this Mr. Baig. Very useful one!
ReplyDeleteHi,
ReplyDeleteThis is interesting, but what if you enter 'brazil', not 'Brazil'? Is there a way to make the AltKey work for such cases?
Regards,
Michal
By default it is case sensitive but you can change the behavior by extending the framework. I will find some links for you later.
DeleteZeeshan
Hello Zeeshan
ReplyDeleteThanks for the blog and its really helpfull, But i have a qury on this
I did the same changes and its working too, but doesnt validate for uniqueness with null value on cloumn
is there any solution for that
Regards,
Sunil
Hi,
DeleteThe objective of this use case is to cover Non-Primary key columns which can be null. If you want columns which does not allow null values then you can put Primary Key constraint on it, ADF will take care automatically for you OR You can put another NOT NULL constraint like I did with UniqueKey in similar way.
Hope you got the point.
Zeeshan
Hi Zeeshan,
ReplyDeleteThis is really helpful. But is there any way in ADF to make it case insensitive along with uniqueness?
Hi Zeeshan,
ReplyDeleteDoes create a unique key on column would also create index. Because it will cause a FULL table scan when a new record is inserted. If not is there a way to create index from ADF EO ?.
Hi,
DeleteADF is middle-tier, this will not add any index to database. Ideally if this is the use case then you should have Unique keys defined at DB level instead of coding at app level. This post is describing that if you don't have those DB constraints but like to get the same functionality.
Hope this clarify a bit.
Zeeshan
Hi,
ReplyDeleteThe solution works fine. However, sometimes it throws this error:
"Too many objects match the primary key null"
If you can shed some light?
Misbah.
Hi Misbah looks like you data might have null values as part of unique key. Also check this post https://stackoverflow.com/questions/20786404/too-many-objects-match-the-primary-key-oracle-jbo-key
DeleteZeeshan
My unique key consists of two columns i.e. userID and RoleID and both columns are 'Not Null'.
DeleteI have checked the post but the scenario is not relevant.
I have an LOV of role assignment to user. I have implemented the unique constraint so that user must not have duplicate roles. It works fine when I select same role again. However, it sometimes throw TooManyObjectsMatchThePrimaryKey exception even I select unique role for userID.
This seems terrible for me since last week. If you can guide in this scenario.
Misbah.