Sunday, November 2, 2014

BPM getLastPerformer() issue (continued): Error when evaluating workflow service XPath extension function, ORABPEL-30043

Long time ago I described my problem with getLastPerformer() xpatch function. Content of this artice you can find here: http://my-java-planet.blogspot.com/2012/11/bpm-getlastperformer-issue-error-in.html

Yesterday I encountered this problem once again. And again, I forget cause of this issue. After some googling, I found my own blog post regarding getLastPerformer().

Fortunatelly, today I know, that you can't use bpm.getLastPerformer() outside of Human Taskflow task (the only place I've seen getLastPerformer() method invoked successfully is from inside the human task's assignment tab), so I can share this knowledge. And this is the whole mystery:)

Friday, June 6, 2014

ADF how to: errors related to bind variables

I accidentally had found an old manual relating to errors related to "bind variables", so I decided share its fragments:

JBO-27122: SQL error during statement preparation

You need to ensure that the list of named bind variables that you reference in your SQL statement matches the list of named bind variables that you've defined on the Bind Variables page of the View Object Editor. Failure to have these two agree correctly can result in one of the following two errors at runtime.
If you use a named bind variable in your SQL statement but have not defined it, you'll receive an error like this:
(oracle.jbo.SQLStmtException) JBO-27122: SQL error during statement preparation.
## Detail 0 ##
(java.sql.SQLException) Missing IN or OUT parameter at index:: 1
 On the other hand, if you have defined a named bind variable, but then forgotten to reference it or mistyped its name in the SQL, then you will see an error like this:
oracle.jbo.SQLStmtException: JBO-27122: SQL error during statement preparation.
## Detail 0 ##
java.sql.SQLException: Attempt to set a parameter name that does not occur in the SQL: LowUserId

Valid query returns no rows

If you do not supply a default value for your named bind variable, it defaults to the NULL value at runtime. This means that if you have a WHERE clause like:
USER_ID = :TheUserId

and you do not provide a default value for the TheUserId bind variable, it will default to having a NULL value and cause the query to return no rows. Where it makes sense for your application, you can leverage SQL functions like NVL(), CASE, DECODE(), or others to handle the situation as you require. In fact, the UserList view object uses a WHERE clause fragment like:
upper(FIRST_NAME) like upper(:TheName)||'%'
so that the query will match any name if the value of :TheName is null.

Error ORA-00904 when adding a Named Bind Variable at Runtime

Assume following situation. Using setNamedWhereClauseParam() method you created code:
ViewObject vo = am.findViewObject("EmployeeList");
vo.setNamedWhereClauseParam("TheName","Jon%");
vo.setNamedWhereClauseParam("HighUserId", new Number(100));
vo.executeQuery();

However, if you run this test program, you actually get a runtime error like this:
oracle.jbo.SQLStmtException: JBO-27122: SQL error during statement preparation.
Statement: 
SELECT * FROM (select USER_ID, EMAIL, FIRST_NAME, LAST_NAME
from EMPLOYEES 
where (upper(FIRST_NAME) like upper(:TheName)||'%'
   or  upper(LAST_NAME)  like upper(:TheName)||'%')
  and USER_ID between :LowUserId and :HighUserId
order by EMAIL) QRSLT  WHERE (user_role = :TheUserRole)
## Detail 0 ##
java.sql.SQLException: ORA-00904: "USER_ROLE": invalid identifier
The root cause of this error is the mechanism that ADF view objects use by default to apply additional runtime WHERE clauses on top of read-only queries.

If you dynamically add an additional WHERE clause at runtime to a read-only view object, its query gets nested into an inline view before applying the additional WHERE clause. For example, suppose your query was defined as:
select USER_ID, EMAIL, FIRST_NAME, LAST_NAME
from EMPLOYEES 
where (upper(FIRST_NAME) like upper(:TheName)||'%'
   or  upper(LAST_NAME)  like upper(:TheName)||'%')
  and USER_ID between :LowUserId and :HighUserId
order by EMAIL 

At runtime, when you set an additional WHERE clause like user_role = :TheUserRole, the framework nests the original query into an inline view like this:
SELECT * FROM(
select USER_ID, EMAIL, FIRST_NAME, LAST_NAME
from EMPLOYEES 
where (upper(FIRST_NAME) like upper(:TheName)||'%'
   or  upper(LAST_NAME)  like upper(:TheName)||'%')
  and USER_ID between :LowUserId and :HighUserId
order by EMAIL) QRSLT
and then adds the dynamic WHERE clause predicate at the end, so that the final query the database sees is:
SELECT * FROM(
select USER_ID, EMAIL, FIRST_NAME, LAST_NAME
from EMPLOYEES 
where (upper(FIRST_NAME) like upper(:TheName)||'%'
   or  upper(LAST_NAME)  like upper(:TheName)||'%')
  and USER_ID between :LowUserId and :HighUserId
order by EMAIL) QRSLT
WHERE user_role = :TheUserRole
This query "wrapping" is necessary in the general case since the original query could be arbitrarily complex. In those cases, simply "gluing" the additional runtime onto the end of the query text could produce unexpected results. By nesting the original query verbatim into an inline view, the view object guarantees that your additional WHERE clause is correctly used to filter the results of the original query, regardless of how complex it is. The downside that you're seeing here with the ORA-00904 error is that the dynamically added WHERE clause can refer only to columns that have been selected in the original query.

ADF how to: service methods

All, what do we find regarding "service methods" in ADF BC documentation can be summarized as follows:

"An application module can expose its data model of view objects to clients without requiring any custom Java code. This allows client code to use the ApplicationModule, ViewObject, RowSet, and Row interfaces in the oracle.jbo package to work directly with any view object in the data model. However, just because you can programmatically manipulate view objects any way you want to in client code doesn't mean that doing so is always a best practice.

Whenever the programmatic code that manipulates view objects is a logical aspect of implementing your complete business service functionality, you should encapsulate the details by writing a custom method in your application module's Java class."
 
You can write your own code to configure view object properties to query the correct data to display, you can perform in custom code any kind of multistep procedural logic or finally you can perform aggregate calculations iterating over one or many view objects.

Adding a service method to an application module has many advantages. Some of them are:
  • allowing multiple client pages to easily call the same code if needed
  • code which can be more clear for the clients (client applications and thier developers)
  • option open to improve your implementation without affecting clients
  • simplifying of the regression-testing of your complete business service
  • enabling declarative invocation of logical business functionality in your pages
To write custom service methods you must enable a custom Java class for an application module:
  • In the Application Navigator, double-click the application module.
  • In the overview editor, click the Java navigation tab.
  • On the Java Classes page, click Edit Java Options.
  • In the Select Java Options dialog, select Generate Application Module Class.
  • Click OK.
After implementing custom code you need publish its to the client. You can do this by publishing custom methods to the application module's client interface. This can be done manually or by wizard available on the Java Classes page of the overview editor for the application module. To publish methods click the Edit icon in the Client Interface section of the page to display the Edit Client Interface dialog.

Thursday, May 29, 2014

ADF how to: how to deal with base class that extends oracle.jbo.serverAppiicationModuleImpl

I have here one ADF exercise:

An application module is named MyAppModule. No Java component is defined for
the module but the application does define a base class that extends oracle.jbo.server.ApplicationModuleImpl.
Which two statements are true in this scenario?
A. Code In the base class will only be implemented if MyAppModuleAppl.java extends the base class.
B. Any code in the base class will be implemented by MyAppModule.
C. No code in the base class will be implemented because an application-specific Java component named MyAppModuleImpl.java does not exist.
D. Any code in the base class will be implemented by MyAppModuleDefimpl.java.
E. The MyAppModule. xml definition will include a reference to the base class.

The first issue here is, if is it possible to ADF Model objects to extend custom classes without defining Java "components". Short answer is: yes, it is.

Mpre info about extending ADF Bussiness Components functionality you can find in Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework. The chapter 36.1 says:

"One of the powerful features of framework-based development is the ability to extend the base framework to change a built-in feature to behave differently or to add a new feature that can be used by all of your applications."

To create your own extension you should create custom Java class which extends selected ADF Business Components component class, by example oracle.jbo.server.ApplicationModuleImpl.

But Developer's Guide says:

"After creating a new framework extension class, it will not automatically be used by your application. You must decide which components in your project should make use of it."

What should be done is select extension class. Every ADF Business Components wizard and editor displays the same Class Extends button on the Java page. Here you can select class which you want extend.

Backing to our test, we have proposed answers from A to E, but which are correct?

A. Wrong, what is " MyAppModuleAppl.java"? Or there is an error in the proposed answer, cause if we will replace MyAppModuleAppl.java with MyAppModuleImpl.java, the answer will be correct.
B. Wrong answer.
C. Correct answer.
D.Also wrong answer, cause our base class extends oracle.jbo.server.ApplicationModuleImpl, and not oracle.jbo.server.ApplicationModuleDefImpl.
E. This is not true, wrong answer.

What do you  think about my answers?

ADF how to: What effect does setting ChangeEventPolicy property to ppr

In this article I would like to solve one of the many issues regarding ADF: what effect does setting ChangeEventPolicy property to ppr.

In the Internet you can find following issue:

You select a binding in the page definition file and set the ChangeEventPolicy property to ppr.
What effect does this action have on the way the page is rendered?
A. It allows a component to partially refresh another component whose partialSubmit  property is set to true.
B. When a user selects a new value In a field, the portion of the page where that component resides is redrawn.
C. It enables you to add a component as a partial target for an event, so that when that event is triggered, the partial target component is refreshed.
D. Components whose values change as a result of back-end logic are automatically repainted.

Cause I found many different solutions, I decided to provide my own:)

Ok. Let's start. In the Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (chapter 22.4.3) you can find following text:

"When you create a form, setting up PPR to work for all the components in the form can be time consuming and error prone. To alleviate this, you can set the changeEventPolicy attribute to ppr on value bindings. Doing so means that anytime the associated component's value changes as a result of backend business logic, the component will be automatically rerendered. You can also set an iterator binding's changeEventPolicy to ppr. When you do this, any action or value binding associated with the iterator will act as though its changeEventPolicy is set to PPR. This allows entire forms to use PPR without your having to configure each component separately."

I think there is not any surprise here. The changeEventPolicy=ppr denotes that when the associated component's value changes the component will be added to list of components provided to partial refresh.

But when partial refresh will happen? The answer we can find in the same tutorial. We can read in the same chapter:

"When you drop a form and elect to include navigation controls, JDeveloper automatically sets the changeEventPolicy attribute on the associated iterator to ppr. JDeveloper also sets each of the navigation buttons' partialSubmit attribute to true. This is how command components notify the framework that PPR should occur."

and next:

"When you set the navigation command components' partialSubmit attribute to true and you set the iterator's changeEventPolicy to ppr, each time a navigation button is clicked, all the components in the form that use the iterator binding are rerendered."

It seems that each partial submit forces also reload of components with changed values and ChangeEventPolicy set to ppr. In other words: to effective use of automatic PPR caused by ChangeEventPolicy we need also any action component with partialSubmit set to true.

OK. We can return to our issue:

A.  Key here is the phrase: "refresh another component whose partialSubmit  property is set to true". A Partial Submit is a method of form submit that does not require a page refresh and only updates components in the view that are referenced from the command component PartialTriggers property. PartialSubmit property should be set to true on the component, action on which should partially submit a form. Setting PartialSubmit property on component which should be refreshed does not make sense. So answer 'A' is wrong.

B. Answer B also does not make sense.

C. Hmm. I think also wrong, answer cause of phrase: "it enables you to add a component as a partial target for an event". As documentation says the component associated with the attribute (or iterator) "will be automatically rerendered", so if automatically, you shouldn't "add a component (manually) as a partial target".

D. My favourite answer is D. Especially because of this sentence in Developer's Guide: "you can set the changeEventPolicy attribute to ppr on value bindings. Doing so means that anytime the associated component's value changes as a result of backend business logic, the component will be automatically rerendered":)




Wednesday, April 30, 2014

Which WebLogic optimization allows one non-XA resource

I was asked about the solution of the following task:

Which WebLogic optimization allows one non-XA resource to participate in a distributed transaction? Select correct answer:
  1. enabling Pinned to Thread 
  2. enabling Logging Last Resource 
  3. increasing the Statement cache size 
  4. setting the statement cache type to LRU 
  5. setting the initial and maximum capacity to the same number 
At start I rejected as absolutely erroneous answers 3 and 5.

Answers 1 and 4 also looked like wrong, but I checked it out:
  • LRU = When you select LRU (Least Recently Used, the default) as the Statement Cache Type, WebLogic Server caches prepared and callable statements used on the connection until the statement cache size is reached.
  • Pinned to Thread = About this documentation says: When Pinned To Thread is enabled, WebLogic Server pins a database connection from the data source to an execution thread the first time an application uses the thread to reserve a connection. When the application finishes using the connection and calls connection.close(), which otherwise returns the connection to the data
    source, WebLogic Server keeps the connection with the execute thread and does not return it to the data source. When an application subsequently requests a connection using the same execute thread, WebLogic Server provides the connection already reserved by the thread.
OK. Correct answer is 2. But WTF is  "Logging Last Resource". At first sight, there is no relation between LLR and transactionability. And .. nothing could be more wrong

Generally, if you have to use global transactions in your applications, you should use an XA JDBC driver. If an XA driver is unavailable for your database, or you prefer not to use an XA driver, you should enable support for global transactions in the data source. And what more (as says Administering JDBC Data Sources for Oracle WebLogic Server12c (12.1.2)), when you select Supports Global Transactions, you must also select the protocol for WebLogic Server to use for the transaction branch when processing a global transaction. One of this is:
  • Logging Last Resource: With this option, the transaction branch in which the connection is used is processed as the last resource in the transaction and is processed as a local transaction. Commit records for two-phase commit (2PC) transactions are inserted in a table on the resource itself, and the result determines the success or failure of the prepare phase of the global transaction. This option offers some performance benefits and greater data safety than Emulate Two-Phase Commit, but it has some limitations.

Sunday, April 27, 2014

Weblogic AGL Transaction Affinity vs. Web Session Affinity

In the world of JEE Application servers the term of "sesssion affinity" denotes that within a cluster of servers, requests from the same client always get routed back to the same server.

Web Session Affinity in Active Grid Link provides analogous functionality, eg. the session affinity policy is used to ensure that all the data base operations for a web session, including transactions, are directed to the same Oracle RAC instance of a RAC cluster. This mechanism is especially usefull because in some circumstances web applications (like shopping applications) have better performance when repeated operations against the same set of records are processed by the same RAC instance.
Applications typically use this type of affinity when:
  • short-lived affinity to an Oracle RAC instance is expected or
  • if the cost (in terms of performance) of being redirected to a new Oracle RAC instance is minimal.
Web Session Affinity should be used for short lived sessions that do not incur a significant penalty when redirecting to a different instance.

Web Session Affinity is a kind of a Connection Affinity which was provided by Oracle RAC Database starting from version 11.1.0.6

Connection Affinity allows a connection pool to select connections that are directed at a specific database instance. The connection pool uses run-time connection load balancing (RCLB) to select an Oracle RAC instance to create the first connection and then subsequent connections are created with an affinity to the same instance.
WebLogic GridLink Data Sources supports:
  • Transaction-based Affinity, 
  • Web Session Affinity and 
  • Data Affinity

The XA Affinity for global transactions ensures all the data base operations for a global transaction performed on an Oracle RAC cluster are directed to the same Oracle RAC instance. The affinity will be established based on the global transaction id, instead of by individual data source, to ensure that connections obtained from different data sources that are configured for the same RAC cluster are all associated with the same RAC instance.
This type of affinity should be used when:
  • the cost (in terms of performance) of being redirected to a new Oracle RAC instance is high (typically during the distributed transaction the cost of a connection redirection to a different Oracle RAC instance is significant) or
  • long-lived affinity to Oracle RAC instance is desired 
Transaction Affinity should be used form long-lived transactions, especially when the performance cost of being redirected to a new Oracle RAC instance is high.