gravatar

Accessing the current locale context

In BC4J , every application module is associated to a locale context object. To access the locale context object associated to the application module use the code snippet given below.

ApplicationModule am=.....
am.getSession().getLocaleContext();

gravatar

Accessing Custom Propeties of Entities

BC4J allows custom properties to be associated to each entity/view object. This can be done declaratively using the overview editor of each object.

To access the value of a custom property (either translated one or the non-translated one), use the following piece of code..

Accessing the custom property value from an entity class

this.getEntityDef().getProperty("propertyName");

The "propertyName" is the name of the property whose value is needed. The property can also be a translatable property. If the property is a translatable property, the above piece of code will fetch the translated value of the LocaleContext associated to the session of the application module..

If the translated value of some other LocaleContext is required then use the following piece of code.

this.getEntityDef().getProperty("propertyName", localeContextObject);

where "localeContextObject" is a java object of type oracle.jbo.LocaleContext.

Accessing the custom property value in viewobject class

In the Impl class just use the method "getProperty"..This takes the same parameters as explained above..

gravatar

Alternate Keys of Entities

All database tables related to functional products, generally have a primary key. In many cases there will be alteast one surrogate key (also called the Alternate key or the Unique key) for each table.

For example , if Employee table is considered, generally "employeeId" will be the primary key. But there can be other columns like "employeeEmail" which has to be unique for each and every employee. Even though this restriction may not be present in the database (i.e database constraint may not be present), functionally it may be required to implement the unique constraint in the middle tier.

BC4J allows you to setup such unique constriants for each entity. This can be done using the Alternate Keys feature.

Using this feature, a set of attributes (of the entity) can be marked to form on alternate keys. Every entity can have more than one alternate key.

So when should alternate keys be created? And what are the advantages of using alternate keys? The following are some of the advantages of using alternate keys.

  1. Business functionality might require a unique key constraint on a set of attributes, and the unique key constraint may not be present at the database level. Then the requirement can be satisfied creating alternate keys. (NOTE: Alternate keys can be created even if there are database constraints)..
  2. Alternate keys are useful for direct row lookups via the "findByAltKey" of the Entity definition.
  3. When alternate keys are created, it becomes easy to check that all entities have unique values for the set of attributes marked as alternate key. Declarative validators can be used to perform this check and to provide appropriate error message. (Even if there are no declarative validators, BC4J framework by default checks whether multiple rows have the same alternate key or not. If its the case, it simply throws an error, which cannot be handled programmatically.)
Primary Key attributes and Alternate Key attributes

The difference between the primary key attributes and the alternate key attributes is that, primary key attributes cannot be null and the alternate key attributes can be null.

Usage of findByAltKey method

The following is a code snippet showing how to find a row(s) using the "findByAltKey"...

Using the "findByAltKey" method from the Entity class
getEntityDef().findByAltKey(this.getDBTransaction(),"alternateKeyName",new Key(new Object[]{"",""}), false,false);
The findByAltKey in the Entity class takes 5 parameters.
  1. The current database transaction.
  2. The name of the alternate key.
  3. The Key object
  4. A boolean value which represents, whether the sub classes (inherited classes) have to be searched or not.
  5. Another boolean value which represents whether to hit the database if no row is found in the entity cache.
Using the "findByAltKey" method from the ViewObject class
findByAltKey("alternateKeyName",new Key(new Object[]{"",""}),true);
The findByAltKey in the ViewObject class takes 3 parameters
  1. The name of the alternate key
  2. The Key object
  3. A boolean value which represents a flag that controls whether, when a db query is issued to get the matching row(s), the view object's current where-clause is to be included in the query or not.

gravatar

font-size

font-size is always inherited by default, i.e every html element gets the font-size of the parent element... The following link from W3C site confirms this..
http://www.w3.org/TR/CSS2/propidx.html

font-size relative values are always relative to the font-size of the parent element.
http://www.w3.org/TR/CSS2/fonts.html#value-def-relative-size

If no font-size is specified then the default font size specified by the browser is considered(and this value can be changed by the end user)...

So setting the font-size to relative units should not cause any problems interms of accessiblity or cross browser compatability.

gravatar

Making an Entity Readonly

In BC4J all the entities that are created are updatable by default. In some cases, entities have to be readonly. To mark an entity as readonly (or non-updatable), do the following.

  • Open the Entity in the design view (i.e open the overview editor)
  • Open the property inspector
  • In the property inspector expand the "Type" tab.
  • There will be a dropdown with the label "Updatable:". Change its value to "false".

gravatar

BC4J batch update feature

This blog tells you the basic information about the batch update feature provided by the BC4J framework .

During the commit phase, BC4J framework by default executes a seperate sql statement for each entity instance that has been either updated or marked as deleted. So if there are 1000 entity instances (of an entity class) which have been either updated or marked as deleted, BC4J framework will execute 1000 appropriate sql statements.

For example, say you have an Employee entity object type for which multiple instances are modified during typical use of the application. If two instances were created, three existing instances modified, and four existing instances deleted, then at transaction commit time the framework issues nine DML statements (2 INSERTs, 3 UPDATEs, and 4 DELETEs) to save these changes.

This can lead to performance problems if the number of changes are huge and if the enity objects are changed very frequently.

To minimize the performance problem, developers need to use the batch update feature of the BC4J framework.

When the batch update feature is enabled, BC4J framework will not execute a seperate sql statement for each and every entity instance during the commit phase. Instead it performs inserts, updates and deletes in batches.

In the example, update batching (with a threshold of 1) causes the framework to issue just three DML statements: one bulk INSERT statement processing two inserts, one bulk UPDATE statement processing three updates, and one bulk DELETE statement processing four deletes.

To enable this feature the only thing that needs to be done is to select the "Use Update Batching" checkbox in the design view of all entity objects as shown below..


Also the input text box with the label "When Number of Entities to Modify Exceeds" has to be set to 1.

Batch operations mean, sending multiple insert/update/delete sql statements in one shot to the sql engine from the middle tier, instead of firing each sql statement.

This feature cannot be used under the following cases..

  • If the entity object has any attributes that are set to Refresh After Insert or Refresh After Update
  • If the Entity has any attributes of type CLOB of BLOB
  • If the entity methods related to performing DML operations, are overridden..(PL/SQL entity objects fall in this category)..

gravatar

SQL Locking basic information in oracle database

When you issue a SELECT statement against the database to query some records, no locks are placed on the selected rows . Rows are locked when the rows have been changed. This means that rows are locked when you issue a "Update" statement. In this situation (i.e when rows are locked by some user) other users will be able to read those records as they appeared before the change ..But they cannot change the contents of the locked row..

In some cases you might want to lock the rows first and then want to update the rows..For this purpose you can use the "for update" and "for update of xxxx" and "for update nowait" options..

For example..
SELECT * FROM EMP WHERE EMPNO=7654 FOR UPDATE NOWAIT

When you issue a SELECT...FOR UPDATE statement, the RDBMS automatically obtains exclusive row-level locks on all the rows identified by the SELECT statement, holding the records "for your changes only" as you move through the rows retrieved by the cursor. No one else will be able to change any of these records until you perform a ROLLBACK or a COMMIT.

This statement (SELECT....FOR UPDATE) will block the user who issued the statement , if it cannot get a lock on any of the rows. To prevent this blocking, user can use the NOWAIT option. If the "NOWAIT" option is provided, then the statement

SELECT...FOR UPDATE NOWAIT
will return an error status if it could'nt lock all the rows identified by the SELECT statement. If its able to lock all the rows, it retuns the result set containing all the rows identified by the SELECT statement and will lock all those rows.


All these locks are realeased once the user commits or rollbacks the data.


After any row is updated and committed, sql maintains information like when a row has been locked and when the lock has been released. This information can be obtained with query like..

SELECT VERSIONS_STARTTIME, VERSIONS_ENDTIME,VERSIONS_XID,
EMPNO FROM EMP VERSIONS BETWEEN TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE AND SYSTIMESTAMP

You can find this information only after committing the data..