Error handling in adf
Posted by
morph
Labels:
ADF
To override the default error handler one can extend the DCErrorHandlerImpl. In this you can process the exceptions or can choose to suppress them. In this post i will explain a way to suppress the RowValException message and display only the detail entity attribute level exception ie AttrValException.
In ADF the exceptions are grouped and raised together as a single object. For example let's say that 2 of the attributes fail the mandatory validation then the exceptions raised for them will be 2 individual AttrValException these are then attached as detail objects into a RowValException and if there are many such RowValException they will be attached and raised together as a TxnValException.
So now to handle the aforementioned task we need to recursively process the exceptions and suppress the RowValException message. The snippet below shows that :-
In this snippet i am recursively processing TxnValException->RowValException -> AttrValException. The AttrValException is being passed in the super call to the DCErrorHandlerImpl to process and display the message.
In ADF the exceptions are grouped and raised together as a single object. For example let's say that 2 of the attributes fail the mandatory validation then the exceptions raised for them will be 2 individual AttrValException these are then attached as detail objects into a RowValException and if there are many such RowValException they will be attached and raised together as a TxnValException.
So now to handle the aforementioned task we need to recursively process the exceptions and suppress the RowValException message. The snippet below shows that :-
public class MyErrorHandler extends DCErrorHandlerImpl {
private static final ADFLogger logger = ADFLogger.createADFLogger(VleAdminErrorHandler.class);
private static ResourceBundle rb = ResourceBundle.getBundle("mypackage.myBundle");
public MyErrorHandler() {
super(true);
}
public MyErrorHandler(boolean setToThrow) {
super(setToThrow);
}
public void reportException(DCBindingContainer bc, java.lang.Exception ex) {
disableAppendCodes(ex);
logger.info("entering reportException() method");
BindingContext ctx = bc.getBindingContext();
String err_code;
err_code = null;
if(ex instanceof NullPointerException){
logger.severe(ex);
JboException e = new JboException(rb.getString("STANDARD_ERROR_MESSAGE"));
super.reportException(bc, e);
}
else if(ex instanceof RowValException){
Object[] exceptions= ((RowValException)ex).getDetails();
if(exceptions!=null){
for(int i=0;i<exceptions.length;i++){
if(exceptions[i] instanceof RowValException){
this.reportException(bc, (Exception)exceptions[i]);
}
else if(exceptions[i] instanceof AttrValException){
super.reportException(bc, (Exception)exceptions[i]);
}
}
}
else{
this.reportException(bc, ex);
}
}
else if (ex instanceof TxnValException) {
Object[] exceptions= ((TxnValException)ex).getDetails();
if(exceptions!=null){
for(int i=0;i<exceptions.length;i++){
if(exceptions[i] instanceof RowValException){
this.reportException(bc, (Exception)exceptions[i]);
}
else{
super.reportException(bc, (Exception)exceptions[i]);
}
}
}
else {
super.reportException(bc, ex);
}
}
else if (ex instanceof oracle.jbo.DMLException) {
JboException e = new JboException(rb.getString("STANDARD_ERROR_MESSAGE"));
super.reportException(bc, e);
}
else if(ex instanceof javax.xml.ws.WebServiceException){
JboException e=new JboException(rb.getString("WEB_SERVICE_EXCEPTION"));
super.reportException(bc, e);
}
else if (ex instanceof JboException) {
super.reportException(bc, ex);
}
}
public static FacesMessage getMessageFromBundle(String key, FacesMessage.Severity severity) {
ResourceBundle bundle = ResourceBundle.getBundle("sahaj.apps.vleadministration.view.resources.VLEAdministrationUIBundle");
String summary = JSFUtil.getStringSafely(bundle, key, null);
String detail = JSFUtil.getStringSafely(bundle, key + "_detail", summary);
FacesMessage message = new FacesMessage(summary, detail);
message.setSeverity(severity);
return message;
}
private void disableAppendCodes(Exception ex) {
if (ex instanceof JboException) {
JboException jboEx = (JboException) ex;
jboEx.setAppendCodes(false);
Object[] detailExceptions = jboEx.getDetails();
if ((detailExceptions != null) && (detailExceptions.length > 0)) {
for (int z = 0, numEx = detailExceptions.length; z < numEx; z++) {
disableAppendCodes((Exception) detailExceptions[z]);
}
}
}
}
@Override
protected boolean skipException(Exception ex) {
if (ex instanceof JboException) {
return false;
} else if (ex instanceof SQLIntegrityConstraintViolationException) {
return true;
}
return super.skipException(ex);
}
@Override
public String getDisplayMessage(BindingContext bindingContext,
Exception exception) {
return super.getDisplayMessage(bindingContext, exception);
}
@Override
public DCErrorMessage getDetailedDisplayMessage(BindingContext bindingContext,
RegionBinding regionBinding,
Exception exception) {
return super.getDetailedDisplayMessage(bindingContext, regionBinding, exception);
}
}
In this snippet i am recursively processing TxnValException->RowValException -> AttrValException. The AttrValException is being passed in the super call to the DCErrorHandlerImpl to process and display the message.
Thursday, November 24, 2011 |
Error handling in adf
2011-11-24T17:22:00+05:30morphADF|
Comments
Optimized update insert ADF ?
I had a recently asked a question on bulk uploads in OTN forum. Seems the performance that i would receive for bulk update/insert scenarios isn't at par.
So i created the procedure and a custom object type and table of that object type which provides far better performance.
Let's say your table structure is as follows :-
So you can basically create a object type mirroring that structure as follows
Then you can basically call this program from the ADF application using struct type. The snippet is shown below:-
This is basically it. This will perform faster than normal ADF update/insert.
So i created the procedure and a custom object type and table of that object type which provides far better performance.
Let's say your table structure is as follows :-
-- TXN_TBL
("TXN_ID" Number,
"USER_NAME" VARCHAR2(50 BYTE),
"TXN_DATE" DATE,
"TXN_AMOUNT" NUMBER)
So you can basically create a object type mirroring that structure as follows
create or replace type TXN_TBL_R is object
("TXN_ID" Number,
"USER_NAME" VARCHAR2(50 BYTE),
"TXN_DATE" DATE,
"TXN_AMOUNT" NUMBER)
and then create a table type that will store record of these types:create or replace type TXN_TBL_TB as table of TXN_TBL_RThe procedure that will perform the updates and or inserts is shown in the below snippet:-
create or replace procedure B_INSERT(p_in IN TXN_TBL_TB) as cursor for_insert is select * from TABLE(p_in) rt where not exists(select tmp.TXN_ID from TXN_TBL tmp where rt.TXN_ID=tmp.TXN_ID); cursor for_update is select * from TABLE(p_in) rt where exists(select tmp.TXN_ID from TXN_TBL tmp where rt.TXN_ID=tmp.TXN_ID); temp_insert TXN_TBL_R; temp_update TXN_TBL_R; begin for temp_update in for_update loop update TXN_TBL tmp set tmp.USER_NAME= temp_update.USER_NAME,tmp.TXN_DATE=temp_update.TXN_DATE,tmp.TXN_AMOUNT=temp_update.TXN_AMOUNT where tmp.TXN_ID= temp_update.TXN_ID; end loop; for temp_insert in for_insert loop insert into TXN_TBL values(temp_insert.TXN_ID, temp_insert.USER_NAME, temp_insert.TXN_DATE, temp_insert.TXN_AMOUNT); end loop; end;
Then you can basically call this program from the ADF application using struct type. The snippet is shown below:-
/**
*@param valueSet the set of bean values
*/
public void someMethod(Set valueSet){
Connection conn=null;
try {
conn = getDBTransaction().createStatement(1).getConnection();
StructDescriptor tblRecordStructType =
StructDescriptor.createDescriptor("TXN_TBL_R", conn);
Iterator it= valueSet.iterator();
Object txnArray[]=new Object[set.size()];
while(it.hasNext()){
SomeCustomBean detail=it.next();
STRUCT tempStruct=new STRUCT(tblRecordStructType,conn,new Object[]{detail.getTranxId(),detail.getUserName(),detail.getTxnDate(),detail.getTransAmount()});
txnArray[i]=tempStruct;
i=i+1;
}
//create array structure descriptor
ArrayDescriptor txnTableDesc=ArrayDescriptor.createDescriptor("TXN_TBL",conn);
//create an Array type with given structure definition
ARRAY txnTableArray=new ARRAY(txnTableDesc,conn,txnArray);
String callableProcedureStatement=" begin TMP_INSERT(?); end;" ;
OracleCallableStatement st=null;
st=(OracleCallableStatement)getDBTransaction().createCallableStatement(callableProcedureStatement, 0);
st.setARRAY(1, txnTableArray);
st.executeUpdate();
this.getDBtransaction().commit();
} catch (JboException e) {
this.getDBtransaction().rollBack();
throw new JboException(e.getMessage());
}
}
This is basically it. This will perform faster than normal ADF update/insert.
Thursday, November 17, 2011 |
Optimized update insert ADF ?
2011-11-17T21:46:00+05:30morphADF|sql|
Comments
Resetting values in popup ADF 11g
Posted by
morph
Labels:
ADF,
jdeveloper11g
If you are using ADF11g version 11.1.1.3 and want to reset the values in the popup, you are not provided with the resetEditableValues option. But you can accomplish this using a custom javascript that i have made.
All you have to do is set clientComponent="true" for all the components that you want to reset and pass the client id of the root component to use this.
Now you have to bind the parent container like panelFormLayout and then on action of the command button use ExtendedRenderKitService to pass the client id of the root component dynamically to resetAction Method so that this script always works. The snippet is shown below.
Hope this will be helpful :D
All you have to do is set clientComponent="true" for all the components that you want to reset and pass the client id of the root component to use this.
resetAction=function(clientId){
var component= AdfPage.PAGE.findComponentByAbsoluteId(clientId);
console.log(component);
var components=component.getDescendantComponents();
this.resetFunction(components);
}
resetFunction=function(components){
for (var i=0;i<components.length;i++){
if(components[i] instanceof AdfRichInputText){
if(components[i].getVisible()&&!components[i].getDisabled()&&!components[i].getReadOnly()){
components[i].setValue("");
}
}
if(components[i] instanceof AdfRichSelectOneChoice){
if(components[i].getVisible()&&!components[i].getDisabled()&&!components[i].getReadOnly()){
components[i].resetValue();
}
}
}
}
Save the contents of this file to a JS file and then import it in your fragment or a jsf page. Now you have to bind the parent container like panelFormLayout and then on action of the command button use ExtendedRenderKitService to pass the client id of the root component dynamically to resetAction Method so that this script always works. The snippet is shown below.
/**
* Resets the popup
* @return null
*/
public String resetPopupAction() {
FacesContext context = FacesContext.getCurrentInstance();
ExtendedRenderKitService erks =
Service.getRenderKitService(context, ExtendedRenderKitService.class);
erks.addScript(context,"resetAction('"+formBinding.getClientId(context) +"')");
return null;
}
Hope this will be helpful :D
Thursday, November 17, 2011 |
Resetting values in popup ADF 11g
2011-11-17T19:09:00+05:30morphADF|jdeveloper11g|
Comments
ora-01086: savepoint 'BO_SP' never established
Posted by
morph
Labels:
ADF,
jdeveloper11g
If you are using ADF 11g and you encounter this issue kindly check your ps_txn table. You can delete the records from this table and then you will see that this error will go away.
This table is used by ADFm internally to serialize user session state to database, so this table has to be monitored and appropriate grants have to be given to the database user so that it can create the database objects.
For more information kindly refer to this article by chris muir.
PS_TXN
This table is used by ADFm internally to serialize user session state to database, so this table has to be monitored and appropriate grants have to be given to the database user so that it can create the database objects.
For more information kindly refer to this article by chris muir.
PS_TXN
Wednesday, September 21, 2011 |
ora-01086: savepoint 'BO_SP' never established
2011-09-21T17:06:00+05:30morphADF|jdeveloper11g|
Comments
Subscribe to:
Posts (Atom)

